1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| import math
# Initial Variable A, B, C, D IV_A = 0x67452301 IV_B = 0xefcdab89 IV_C = 0x98badcfe IV_D = 0x10325476
# Nonlinear function 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)))
# Loop Left Shift L = lambda x, n:(((x << n) | (x >> (32 - n))) & (0xffffffff))
# 每次循环左移的位数 Shi = ((7, 12, 17, 22) * 4, (5, 9, 14, 20) * 4, (4, 11, 16, 23) * 4, (6, 10, 15, 21) * 4)
# 每次 M[i](消息分片)次序。 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 LittleEndian(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 str2Bin(m): return "".join('{:08b}'.format(ord(x)) for x in m)
# 模2的32次方加 def addMod2_32(a, b): return (a + b) % (2 ** 32)
# 产生常数T[i],常数有可能超过32位,需要&0xffffffff操作 # 返回的是十进制的数。 def T(i): result = (int(4294967296 * abs(math.sin(i)))) & 0xffffffff return result
def MD5(m): ## str to binstr m = str2Bin(m) lm = len(m) ## Padding lm_mod = lm % 512 ### 若原始消息长度刚好满足模512与448同余 ### 则还需要填充512位 if lm_mod == 448: FillLength = 512 elif lm_mod > 448: FillLength = 512 + 448 - lm_mod else: FillLength = 448 - lm_mod m += '1' + (FillLength - 1) * '0' # Padding length length = LittleEndian(bin(lm % (2 ** 64))[2:].zfill(64), False) m += length lm = len(m) ## Generate Initial Variable(IV) A, B, C, D = IV_A, IV_B, IV_C, IV_D for i in range(0, lm, 512): Y = m[i:i + 512] for j in range(4): # 共4轮 for k in range(16): # 每轮16个步骤 # A, B, C, D Backup AA, BB, CC, DD = A, B, C, D ## Nonlinear function 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 = LittleEndian(Y[M[j][k] * 32:M[j][k] * 32 + 32], False) A, C, D = DD, BB, CC B = addMod2_32(AA, t) B = addMod2_32(B, int(M_j, 2)) B = addMod2_32(B, T_i) B = L(B, Shi[j][k]) B = addMod2_32(B, BB) ans1 = LittleEndian(hex(addMod2_32(A, IV_A))[2:-1], True).zfill(8) ans2 = LittleEndian(hex(addMod2_32(B, IV_B))[2:-1], True).zfill(8) ans3 = LittleEndian(hex(addMod2_32(C, IV_C))[2:-1], True).zfill(8) ans4 = LittleEndian(hex(addMod2_32(D, IV_D))[2:-1], True).zfill(8) return ans1 + ans2 + ans3 + ans4
def main(): m = input("请输入明文: ") ans = MD5(m) print("明文加密后的密文是:\n" + MD5(m) + " (Lowercase)\n" + ans.upper() + " (Uppercase)")
if __name__ == '__main__': main()
|