Source: How About a Nice Game of Chess?
Part 1: Generate a series of hashes: MD5(salt + index). For each hash starting with five zeros, write down the sixth character.
First, a helper function to generate an infinite list of natural numbers:
def naturals(i = 0): while True: yield i i += 1
I have since learned that this function already exists in the standard library:
. So it goes.
Then a second helper that will take a string and return its MD5 hash (in hex format):
def md5(str): return hashlib.md5(str.encode()).hexdigest()
Then we just have to keep going until we have enough of a password:
password = '' for i in naturals(): hash = md5(args.salt + str(i)) if hash[:5] == '00000': password += hash if len(password) == 8: break print(password)
Part 2: The sixth character now represents the position (0-7) in the password to write (only use the first write to each position; ignore 8-F as the sixth character). The seventh is the actual password character.
This one is somewhat more interesting. You have to:
- Determine where the new character would go and if that spot is available
- Determine what the new character would be
- Figure out when we’ve found all 8 characters
hard_password = ['-'] * 8 for i in naturals(): hash = md5(args.salt + str(i)) if hash[:5] == '00000': index = hash if index not in '01234567': continue index = int(index) if hard_password[index] != '-': continue hard_password[index] = hash if not(any(c == '-' for c in hard_password)): break print(hard_password)
On fun thing you can do with the full source for today’s solution is watch the progress as it cracks the password: