# AoC 2016 Day 5: Password Cracker

### 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: itertools.count . 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':

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[5]
if index not in '01234567':
continue

index = int(index)
continue

print(hard_password)
I like Python’s any function. It reminds me of more functional programming paradigms.