58 lines
1.3 KiB
Python
58 lines
1.3 KiB
Python
import hashlib
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class Candidate:
|
|
char: str
|
|
age: int
|
|
orig_hash: int
|
|
conf_hash: int = 0
|
|
|
|
data = "cuanljph"
|
|
# data = "abc"
|
|
|
|
keys = []
|
|
candidates = []
|
|
rehashs = 2016 # part 2
|
|
rehashs = 0 # part 1
|
|
|
|
for hash_idx in range(0, 100_000):
|
|
h = hashlib.md5(f"{data}{hash_idx}".encode()).hexdigest()
|
|
for _ in range(rehashs):
|
|
h = hashlib.md5(h.encode()).hexdigest()
|
|
|
|
idx3 = None
|
|
for i in range(len(h) - 3):
|
|
if all([h[i] == h[i + j] for j in range(3)]):
|
|
idx3 = i
|
|
break
|
|
|
|
if idx3 is not None:
|
|
candidates.append(Candidate(h[idx3], 0, hash_idx))
|
|
|
|
letters = []
|
|
for i in range(len(h) - 5):
|
|
if all([h[i] == h[i + j] for j in range(5)]):
|
|
letters.append(h[i])
|
|
|
|
for current_char in set(letters):
|
|
for c in candidates:
|
|
if c.char == current_char and c.age > 0:
|
|
# print(f"Confirmed {c} at {hash_idx}.")
|
|
keys.append(c)
|
|
c.age = 1000 # mark for removal from candidates
|
|
c.conf_hash = hash_idx
|
|
|
|
if len(keys) >= 64:
|
|
# print("done")
|
|
break
|
|
|
|
# remove old candidates
|
|
candidates = [c for c in candidates if c.age < 1000]
|
|
for c in candidates:
|
|
c.age += 1
|
|
|
|
keys.sort(key=lambda c: c.orig_hash)
|
|
print(keys[63].orig_hash)
|