diff --git a/hashes/md5.py b/hashes/md5.py new file mode 100644 index 000000000..ff32f4c2e --- /dev/null +++ b/hashes/md5.py @@ -0,0 +1,107 @@ +import math + +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') + 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 + + 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 ] + + 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(): + assert md5me("") == "d41d8cd98f00b204e9800998ecf8427e" + assert md5me("The quick brown fox jumps over the lazy dog") == "9e107d9d372bb6826bd81d3542a419d6" + print("Success.") + + +if __name__ == "__main__": + test()