密码学课程设计之MD5
#coding:utf-8 import math def str_bin(string): a = '' for i in string: f = bin(ord(i))[2:] f = '0'*(8-len(f)) + f a += f return a def Little_Endian(s,Hex): l = len(s) ans = '' if Hex == False: i = l - 8 while i >= 0: ans += s[i:i+8] i -= 8 else: i = l - 2 while i >= 0 : ans += s[i:i+2] i -= 2 return ans def T(i): res = (int(4294967296*abs(math.sin(i))))&0xffffffff return res def addMod32(a,b): return (a+b)%(2**32) M = ((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), (1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12), (5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2), (0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9)) def MD5(m): iv_A = 0x67452301 iv_B = 0xefcdab89 iv_C = 0x98badcfe iv_D = 0x10325476 s_list = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7,12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10,15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21] F = lambda x,y,z:((x&y)|((~x)&z)) G = lambda x,y,z:((x&z)|(y&(~z))) H = lambda x,y,z:(x^y^z) I = lambda x,y,z:(y^(x|(~z))) L = lambda x,n:(((x<<n)|(x>>32-n)))&(0xffffffff) m = str_bin(m) lm = len(m) lm_mod = lm%512 if lm_mod == 448: f_length = 512 elif lm_mod > 448: f_length = 512 + 448 - lm_mod else: f_length = 448 - lm_mod m += '1' + (f_length-1)*'0' m_padding = Little_Endian(bin(lm%(2**64))[2:].zfill(64),False) m += m_padding lm = len(m) A, B, C, D = iv_A, iv_B, iv_C, iv_D for i in range(0,lm,512): Y = m[i:i+512] A1, B1, C1, D1 = A, B, C, D for j in range(4): for k in range(16): AA, BB, CC, DD = A, B, C, D if j == 0: t = F(B,C,D) elif j == 1: t = G(B,C,D) elif j == 2: t = H(B,C,D) else: t = I(B,C,D) T_i = T(16*j + k + 1) M_j = Little_Endian(Y[M[j][k]*32:M[j][k]*32+32],False) A, C, D = DD, BB, CC B = addMod32(AA,t) B = addMod32(B,int(M_j,2)) B = addMod32(B,T_i) B = L(B,s_list[16*j + k]) B = addMod32(B,BB) A = addMod32(A,A1) B = addMod32(B,B1) C = addMod32(C,C1) D = addMod32(D,D1) ans1 = Little_Endian(hex(A)[2:-1],True).zfill(8) ans2 = Little_Endian(hex(B)[2:-1],True).zfill(8) ans3 = Little_Endian(hex(C)[2:-1],True).zfill(8) ans4 = Little_Endian(hex(D)[2:-1],True).zfill(8) return ans1+ans2+ans3+ans4 m = 'cumt' print "明文:%s\nMD5加密:%s"%(m,MD5(m).upper())