I think I know how rainbow table works , I just wanted to make basic reduction function(for md5) in python with an approach that I am not taking a certain portion of hash but am taking the full hash and introducing below reduction function with an error handling method below is code.
Q1. is it necessary to take first or last or a portion of hash, what i mean is say a03d4d52516c03932b6815fe6c6f4151 (hexdigest) for this hash can i take every 8 bit and try to convert it to ASCII if that fails / goes out of ASCII range(90) then do nothing and try for next 8 bit. Please be informed i generated hash using utf-8 encoding.
Q2. Even i am able to generate plain text but result contains null bytes and if i use strip() to get rid of null bytes to generate the next hash on plain text result then hash changes. does md5 calculate on null bytes too ?
Result: v;92T/Mm - first plain text with no split() - hash=87aef402508bc715a1cf37b7ffe3c7ea
v;92T/Mm - first plain text with split() to get rid of null bytes hash=fc9d09e27c4ee842f7e262eb6a190da1
Code I tried(please run it to validate:
"""Trying a basic reduction function R1 , md5 Rainbow table new apporoach. here am not taking ony last x bits of hexdihest hash always, it is randomized through error checking Conventional reference: How to create reduction functions in rainbow tables?"""
import hashlib, functools, time, codecs
1. Constant hash function to be applied on the domain of P of f(H); where p belongs to P which is a finite set of alphanumeric character
def H(p): return hashlib.md5(p.encode('utf-8')).hexdigest()
2. constant split function to operate on 8 bit ascii char set
Note I could do a utf-16 and 16 bits operation to generate other european charcter; but I only want to reduce hexdigest of hash to ascii readable char.
Note If i use utf-16 then it will give me again 128 bits printable charactr in return as i dont need to put any error checking to get the result !
p=input("Gimme your password !\n") h=H(p) def R1(h): L= x=0 for i in range(0,16): bit_op_8=h[x:l(x)] x+=2 try: L.append(codecs.decode(codecs.decode(bit_op_8,'hex'),'ascii')) except UnicodeDecodeError: pass c="" for j in range(0,len(L)): c+=L[j] return c result=R1(h) print("after Reduction: ",result)
3.second hashing: f(H1)=f(H) but H1 takes R1(f(H))
#Here without using a strip() and not caring about null bytes reduced=result print(H(reduced)) #Here including nullbytes in result reduced=result reduced1=str(reduced).strip() print(H(reduced1))