-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMD5.py
122 lines (96 loc) · 3.04 KB
/
MD5.py
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
117
118
119
120
121
122
import math
s = [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, ]
def rearrange(bitString32):
if len(bitString32) != 32:
raise ValueError("Need length 32")
newString = ""
for i in [3, 2, 1, 0]:
newString += bitString32[8 * i: 8 * i + 8]
return newString
def reformatHex(i):
hexrep = format(i, "08x")
thing = ""
for i in [3, 2, 1, 0]:
thing += hexrep[2 * i: 2 * i + 2]
return thing
def pad(bitString):
startLength = len(bitString)
bitString += "1"
while len(bitString) % 512 != 448:
bitString += "0"
lastPart = format(startLength, "064b")
#lastPart = "{0:064b}".format(startLength)
bitString += rearrange(lastPart[32:]) + rearrange(lastPart[:32])
return bitString
def getBlock(bitString):
currPos = 0
while currPos < len(bitString):
currPart = bitString[currPos: currPos + 512]
mySplits = []
for i in range(16):
mySplits.append(int(rearrange(currPart[32 * i: 32 * i + 32]), 2))
yield mySplits
currPos += 512
def not32(i):
i_str = format(i, "032b")
new_str = ""
for c in i_str:
new_str += "1" if c == "0" else "0"
return int(new_str, 2)
def sum32(a, b):
return (a + b) % 2 ** 32
def leftrot32(i, s):
return (i << s) ^ (i >> (32 - s))
def md5me(testString):
bs = ""
for i in testString:
bs += format(ord(i), "08b")
bs = pad(bs)
tvals = [int(2 ** 32 * abs(math.sin(i + 1))) for i in range(64)]
a0 = 0x67452301
b0 = 0xEFCDAB89
c0 = 0x98BADCFE
d0 = 0x10325476
for m in getBlock(bs):
A = a0
B = b0
C = c0
D = d0
for i in range(64):
if i <= 15:
# f = (B & C) | (not32(B) & D)
f = D ^ (B & (C ^ D))
g = i
elif i <= 31:
# f = (D & B) | (not32(D) & C)
f = C ^ (D & (B ^ C))
g = (5 * i + 1) % 16
elif i <= 47:
f = B ^ C ^ D
g = (3 * i + 5) % 16
else:
f = C ^ (B | not32(D))
g = (7 * i) % 16
dtemp = D
D = C
C = B
B = sum32(B, leftrot32((A + f + tvals[i] + m[g]) % 2 ** 32, s[i]))
A = dtemp
a0 = sum32(a0, A)
b0 = sum32(b0, B)
c0 = sum32(c0, C)
d0 = sum32(d0, D)
digest = reformatHex(a0) + reformatHex(b0) + \
reformatHex(c0) + reformatHex(d0)
return digest
def test():
print(md5me("hellowwwwwwwwww"))
assert (
md5me("The quick brown fox jumps over the lazy dog")
== "9e107d9d372bb6826bd81d3542a419d6"
)
print("Success.")
if __name__ == "__main__":
test()