Given is a md5 hash of a five digits long PIN. It is given as string.
Md5 is a function to hash your password:
"password123" ===> "482c811da5d5b4bc6d497ffa98491e38"

Why is this useful?
Hash functions like md5 can create a hash from string in a short time and it is impossible to find out the password, if you only got the hash. The only way is cracking it, means try every combination, hash it and compare it with the hash you want to crack. (There are also other ways of attacking md5 but that's another story)
Every Website and OS is storing their passwords as hashes, so if a hacker gets access to the database, he can do nothing, as long the password is safe enough.

What is a hash:
https://en.wikipedia.org/wiki/Hash_function#:~:text=A%20hash%20function%20is%20any,table%20called%20a%20hash%20table.

What is md5:
https://en.wikipedia.org/wiki/MD5

Note: Many languages have build in tools to hash md5. If not, you can write your own md5 function or google for an example.

Here is another kata on generating md5 hashes:
https://www.codewars.com/kata/password-hashes

Your task is to return the cracked PIN as string.

This is a little fun kata, to show you, how weak PINs are and how important a bruteforce protection is, if you create your own login.

If you liked this kata, here is an extension with short passwords:
https://www.codewars.com/kata/59146f7b4670ba520900000a

Source: codewars | Difficulty: EASY

Starter code: def crack(hash):
	

Solutions:
import hashlib

def crack(hash):
	for i in range(100000):
		if hashlib.md5(str(i).zfill(5).encode()).hexdigest() == hash:
			return str(i).zfill(5)


from hashlib import md5
from itertools import product

def crack(hash):
	for bs in map(bytes, product(b'0123456789', repeat=5)):
		if md5(bytes(bs)).hexdigest() == hash:
			return bs.decode()


import hashlib

def create_crack(n):
	rainbow = {hashlib.md5(f'{a:05}'.encode()).hexdigest(): f'{a:05}' for a in range(10 ** n)}
	return rainbow.get
crack = create_crack(6)


from itertools import product
from string import digits
from hashlib import md5
crack = {md5(pin.encode()).hexdigest(): pin for pin in map(''.join, product(digits, repeat=5))}.get


import hashlib
lookup = [hashlib.md5(('0000' + str(i))[-5:].encode()).hexdigest() for i in range(100000)]

def crack(hash):
	index = lookup.index(hash)
	return ('0000' + str(index))[-5:]


from hashlib import md5

def crack(hash):
	for pin in [str(x).rjust(5, '0') for x in range(0, 100000)]:
		if md5(pin.encode()).hexdigest() == hash:
			return pin


import hashlib

def crack(hash):
	for i in range(0, 99999):
		pin = digit_to_pin(i).encode()
		rand_hash = hashlib.md5(pin).hexdigest()
		if hash == rand_hash:
			return pin.decode()
		else:
			pass

def digit_to_pin(digit):
	string = str(digit)
	if len(string) < 5:
		nulls = (5 - len(string)) * '0'
		string = nulls + string
	return string


from hashlib import md5
from itertools import product

def crack(hash):
	digits = [str(x) for x in range(10)]
	return next((s for s in map(lambda tup: ''.join(tup), product(digits, repeat=5)) if md5(bytes(s, 'utf-8')).hexdigest() == hash))


from hashlib import md5

def crack(hash):
	for i in range(10 ** 5):
		s = b'%05d' % i
		if md5(s).hexdigest() == hash:
			return s.decode()


import hashlib

def crack(hash):
	return [str(x) for x in range(100000) if hashlib.md5('{0:05}'.format(x).encode()).hexdigest() == hash][0].zfill(5)