Entry 3605
md5 in pure python
Submitted by anonymous
on April 22, 2010 at 1:41 p.m.
Language: Python. Code size: 8.8 KB.
#!/usr/bin/env python """ Copyright 2010 kenkeiras <kenkeiras@gmail.com> Bajo la licencia WTFPL DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. """ # Invierte un string de hexadecimales def hexinvert(h,s): if (h[-1]=='L'): # La L de long h=h[0:-1] while len(h)<s: h="0"+h l=[] i=0 while i <len(h): l.append(str(h[i])+str(h[i+1])) i+=2 r="" while l !=[]: r+=l.pop(len(l)-1) return r #Pasa un entero de 4 bytes a un array de 4 bytes def uint4tochar(s): i=0 t=[0,0,0,0] while i<4: aux=(s>>(8*i))&0xFF t[3-i]=int(aux) i+=1 return t #Devuelve un hexadecimal con 4 caracteres o mas def myhex(a): r=hex(a) if (len(r)==3): r="0x0"+r[2] return r #Funciones basicas def F(x,y,z): return (x&y)|((~x&0xFFFFFFFF)&z) def G(x,y,z): return (x&z)|(y&(~z&0xFFFFFFFF)) def H(x,y,z): return x^y^z def I(x,y,z): return y^(x|(~z&0xFFFFFFFF)) # Rotacion def rotate_left(x,y): return ((x<<y)|(x>>(32-y))) #Transformaciones def FF(a,b,c,d,x,s,ac): a=(a+(F(b,c,d)+x+ac))&0xFFFFFFFF a= rotate_left(a,s)&0xFFFFFFFF a=(a+b)&0xFFFFFFFF return a def GG(a,b,c,d,x,s,ac): a=(a+(G(b,c,d)+x+ac))&0xFFFFFFFF a= rotate_left(a,s)&0xFFFFFFFF a=(a+b)&0xFFFFFFFF return a def HH(a,b,c,d,x,s,ac): a=(a+(H(b,c,d)+x+ac))&0xFFFFFFFF a= rotate_left(a,s)&0xFFFFFFFF a=(a+b)&0xFFFFFFFF return a def II(a,b,c,d,x,s,ac): a=(a+(I(b,c,d)+x+ac))&0xFFFFFFFF a= rotate_left(a,s)&0xFFFFFFFF a=(a+b)&0xFFFFFFFF return a #Tabla de valores utilizados en la funcion S11=7 S12=12 S13=17 S14=22 S21=5 S22=9 S23=14 S24=20 S31=4 S32=11 S33=16 S34=23 S41=6 S42=10 S43=15 S44=21 class md5: #Paso 1, se anhade un bit '1' al mensaje # Y despues se hace que sea igual a 448, modulo 512 (ambos en bits) # ,que se traducen en 56 y 64 bytes respectivamente def padd(self,s): self.stream=s+"\x80" while ((len(self.stream)%64)!=56): self.stream+="\x00" #Paso 2, se anhade al mensaje el numero (de 64 bits-8 bytes) # de bits antes de la primera adicion def attach_len(self,ln): ln%=1<<64 i=7 l=[] while i>=0: k=256**i aux=ln/k l.append(aux) ln-=aux*(k) i-=1 while len(l)>0: self.stream+=chr(l.pop(len(l)-1)) #Paso 3, se inicializa un bufer def buff_init(self): self.a = 0x67452301 self.b = 0xefcdab89 self.c = 0x98badcfe self.d = 0x10325476 # Paso 4, se procesa el objeto def transform(self,x): AA=self.a BB=self.b CC=self.c DD=self.d #Ronda 1 AA=FF (AA, BB, CC, DD, x[ 0], S11, 0xd76aa478) # 1 DD=FF (DD, AA, BB, CC, x[ 1], S12, 0xe8c7b756) # 2 CC=FF (CC, DD, AA, BB, x[ 2], S13, 0x242070db) # 3 BB=FF (BB, CC, DD, AA, x[ 3], S14, 0xc1bdceee) # 4 AA=FF (AA, BB, CC, DD, x[ 4], S11, 0xf57c0faf) # 5 DD=FF (DD, AA, BB, CC, x[ 5], S12, 0x4787c62a) # 6 CC=FF (CC, DD, AA, BB, x[ 6], S13, 0xa8304613) # 7 BB=FF (BB, CC, DD, AA, x[ 7], S14, 0xfd469501) # 8 AA=FF (AA, BB, CC, DD, x[ 8], S11, 0x698098d8) # 9 DD=FF (DD, AA, BB, CC, x[ 9], S12, 0x8b44f7af) # 10 CC=FF (CC, DD, AA, BB, x[10], S13, 0xffff5bb1) # 11 BB=FF (BB, CC, DD, AA, x[11], S14, 0x895cd7be) # 12 AA=FF (AA, BB, CC, DD, x[12], S11, 0x6b901122) # 13 DD=FF (DD, AA, BB, CC, x[13], S12, 0xfd987193) # 14 CC=FF (CC, DD, AA, BB, x[14], S13, 0xa679438e) # 15 BB=FF (BB, CC, DD, AA, x[15], S14, 0x49b40821) # 16 # Round 2 AA=GG (AA, BB, CC, DD, x[ 1], S21, 0xf61e2562) # 17 DD=GG (DD, AA, BB, CC, x[ 6], S22, 0xc040b340) # 18 CC=GG (CC, DD, AA, BB, x[11], S23, 0x265e5a51) # 19 BB=GG (BB, CC, DD, AA, x[ 0], S24, 0xe9b6c7aa) # 20 AA=GG (AA, BB, CC, DD, x[ 5], S21, 0xd62f105d) # 21 DD=GG (DD, AA, BB, CC, x[10], S22, 0x2441453) # 22 CC=GG (CC, DD, AA, BB, x[15], S23, 0xd8a1e681) # 23 BB=GG (BB, CC, DD, AA, x[ 4], S24, 0xe7d3fbc8) # 24 AA=GG (AA, BB, CC, DD, x[ 9], S21, 0x21e1cde6) # 25 DD=GG (DD, AA, BB, CC, x[14], S22, 0xc33707d6) # 26 CC=GG (CC, DD, AA, BB, x[ 3], S23, 0xf4d50d87) # 27 BB=GG (BB, CC, DD, AA, x[ 8], S24, 0x455a14ed) # 28 AA=GG (AA, BB, CC, DD, x[13], S21, 0xa9e3e905) # 29 DD=GG (DD, AA, BB, CC, x[ 2], S22, 0xfcefa3f8) # 30 CC=GG (CC, DD, AA, BB, x[ 7], S23, 0x676f02d9) # 31 BB=GG (BB, CC, DD, AA, x[12], S24, 0x8d2a4c8a) # 32 # Round 3 AA=HH (AA, BB, CC, DD, x[ 5], S31, 0xfffa3942) # 33 DD=HH (DD, AA, BB, CC, x[ 8], S32, 0x8771f681) # 34 CC=HH (CC, DD, AA, BB, x[11], S33, 0x6d9d6122) # 35 BB=HH (BB, CC, DD, AA, x[14], S34, 0xfde5380c) # 36 AA=HH (AA, BB, CC, DD, x[ 1], S31, 0xa4beea44) # 37 DD=HH (DD, AA, BB, CC, x[ 4], S32, 0x4bdecfa9) # 38 CC=HH (CC, DD, AA, BB, x[ 7], S33, 0xf6bb4b60) # 39 BB=HH (BB, CC, DD, AA, x[10], S34, 0xbebfbc70) # 40 AA=HH (AA, BB, CC, DD, x[13], S31, 0x289b7ec6) # 41 DD=HH (DD, AA, BB, CC, x[ 0], S32, 0xeaa127fa) # 42 CC=HH (CC, DD, AA, BB, x[ 3], S33, 0xd4ef3085) # 43 BB=HH (BB, CC, DD, AA, x[ 6], S34, 0x4881d05) # 44 AA=HH (AA, BB, CC, DD, x[ 9], S31, 0xd9d4d039) # 45 DD=HH (DD, AA, BB, CC, x[12], S32, 0xe6db99e5) # 46 CC=HH (CC, DD, AA, BB, x[15], S33, 0x1fa27cf8) # 47 BB=HH (BB, CC, DD, AA, x[ 2], S34, 0xc4ac5665) # 48 # Round 4 AA=II (AA, BB, CC, DD, x[ 0], S41, 0xf4292244) # 49 DD=II (DD, AA, BB, CC, x[ 7], S42, 0x432aff97) # 50 CC=II (CC, DD, AA, BB, x[14], S43, 0xab9423a7) # 51 BB=II (BB, CC, DD, AA, x[ 5], S44, 0xfc93a039) # 52 AA=II (AA, BB, CC, DD, x[12], S41, 0x655b59c3) # 53 DD=II (DD, AA, BB, CC, x[ 3], S42, 0x8f0ccc92) # 54 CC=II (CC, DD, AA, BB, x[10], S43, 0xffeff47d) # 55 BB=II (BB, CC, DD, AA, x[ 1], S44, 0x85845dd1) # 56 AA=II (AA, BB, CC, DD, x[ 8], S41, 0x6fa87e4f) # 57 DD=II (DD, AA, BB, CC, x[15], S42, 0xfe2ce6e0) # 58 CC=II (CC, DD, AA, BB, x[ 6], S43, 0xa3014314) # 59 BB=II (BB, CC, DD, AA, x[13], S44, 0x4e0811a1) # 60 AA=II (AA, BB, CC, DD, x[ 4], S41, 0xf7537e82) # 61 DD=II (DD, AA, BB, CC, x[11], S42, 0xbd3af235) # 62 CC=II (CC, DD, AA, BB, x[ 2], S43, 0x2ad7d2bb) # 63 BB=II (BB, CC, DD, AA, x[ 9], S44, 0xeb86d391) # 64 self.a=(self.a+AA)&0xFFFFFFFF self.b=(self.b+BB)&0xFFFFFFFF self.c=(self.c+CC)&0xFFFFFFFF self.d=(self.d+DD)&0xFFFFFFFF def update(self,ln): i=0 while i<(len(self.stream)/64): j=0 x=[] while j<16: t=((ord(self.stream[(i*64)+(j*4)+0]))| (ord(self.stream[(i*64)+(j*4)+1])<< 8)| (ord(self.stream[(i*64)+(j*4)+2])<< 16)| (ord(self.stream[(i*64)+(j*4)+3])<< 24)) x.append(t) j+=1 self.transform(x) i+=1 # Paso 5, finalizacion y salida def final(self): self.digest=[] for some in [self.a,self.b,self.c,self.d]: t=uint4tochar(some) while len(t)>0: thing=t.pop(len(t)-1) self.digest.append(myhex(thing)[2:4]) def hexdigest(self): from string import join return join(self.digest,'') # Punto de inicio def __init__(self,s): ln=len(s)*8 self.padd(s) self.attach_len(ln) self.buff_init() self.update(ln) self.final() if __name__=="__main__": import hashlib tests=["","1234","The quick brown fox jumps over the lazy dog","The quick brown fox jumps over the lazy dog.","qwertyuiopasdfghjklzxcvbnm,.+'-.,!\"$%&/()=?!~|@#{[]}"] for s in tests: chksum=md5(s) a=chksum.hexdigest() print a,'=', b=hashlib.md5(s).hexdigest() print b,a==b
This snippet took 0.07 seconds to highlight.
Back to the Entry List or Home.