zoukankan      html  css  js  c++  java
  • python实现md5

    流程图

    4组线性函数

    F(x,y,z) = (x & y) | (~x & z)
    G(x,y,z) = (x & z) | (y & ~z) 
    H(x,y,z) = x ^ y ^ z
    I(x,y,z) = y ^ ( x | ~z)
    

    移位数组如下

    0~15次 [7, 12, 17, 22]
    16~31次 [5,  9, 14, 20]
    32~47次 [4, 11, 16, 23]
    48~63次 [6, 10, 15, 21]
    

    正弦函数表

    #key值64个是固定的,计算方法是ki= floor(2^32*abs(sin(i+1)))
    
    SV = [0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf,
          0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af,
          0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e,
          0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
          0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6,
          0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
          0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122,
          0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
          0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 0xd9d4d039,
          0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97,
          0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d,
          0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
          0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391]
    

    python代码实现

    import binascii
    import sys
    import os.path
    
    
    SV = [0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf,
          0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af,
          0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e,
          0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
          0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6,
          0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
          0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122,
          0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
          0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 0xd9d4d039,
          0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97,
          0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d,
          0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
          0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391]
    
    
    # 根据ascil编码把字符转成对应的二进制
    def binvalue(val, bitsize):
        binval = bin(val)[2:] if isinstance(val, int) else bin(ord(val))[2:]
        if len(binval) > bitsize:
            raise ("binary value larger than the expected size")
        while len(binval) < bitsize:
            binval = "0" + binval
        return binval
    
    
    def string_to_bit_array(text):
        array = list()
        for char in text:
            binval = binvalue(char, 8)
            array.extend([int(x) for x in list(binval)])
        return array
    
    
    # 循环左移
    def leftCircularShift(k, bits):
        bits = bits % 32
        k = k % (2 ** 32)
        upper = (k << bits) % (2 ** 32)
        result = upper | (k >> (32 - (bits)))
        return (result)
    
    
    # 分块
    def blockDivide(block, chunks):
        result = []
        size = len(block) // chunks
        for i in range(0, chunks):
            result.append(int.from_bytes(block[i * size:(i + 1) * size], byteorder="little"))
        return result
    
    
    # F函数作用于“比特位”上
    # if x then y else z
    def F(X, Y, Z):
        compute = ((X & Y) | ((~X) & Z))
        return compute
    
    
    # if z then x else y
    def G(X, Y, Z):
        return ((X & Z) | (Y & (~Z)))
    
    
    # if X = Y then Z else ~Z
    def H(X, Y, Z):
        return (X ^ Y ^ Z)
    
    
    def I(X, Y, Z):
        return (Y ^ (X | (~Z)))
    
    
    # 四个F函数
    def FF(a, b, c, d, M, s, t):
        result = b + leftCircularShift((a + F(b, c, d) + M + t), s)
        return (result)
    
    
    def GG(a, b, c, d, M, s, t):
        result = b + leftCircularShift((a + G(b, c, d) + M + t), s)
        return (result)
    
    
    def HH(a, b, c, d, M, s, t):
        result = b + leftCircularShift((a + H(b, c, d) + M + t), s)
        return (result)
    
    
    def II(a, b, c, d, M, s, t):
        result = b + leftCircularShift((a + I(b, c, d) + M + t), s)
        return (result)
    
    
    # 数据转换
    def fmt8(num):
        bighex = "{0:08x}".format(num)
        binver = binascii.unhexlify(bighex)
        result = "{0:08x}".format(int.from_bytes(binver, byteorder='little'))
        return (result)
    
    
    # 计算比特长度
    def bitlen(bitstring):
        return len(bitstring) * 8
    
    
    def md5sum(msg):
        # 计算比特长度,如果内容过长,64个比特放不下。就取低64bit。
        msgLen = bitlen(msg) % (2 ** 64)
        # 先填充一个0x80,其实是先填充一个1,后面跟对应个数的0,因为一个明文的编码至少需要8比特,所以直接填充 0b10000000即0x80
        msg = msg + b'x80'  # 0x80 = 1000 0000
        # 似乎各种编码,即使是一个字母,都至少得1个字节,即8bit才能表示,所以不会出现原文55bit,pad1就满足的情况?可是不对呀,要是二进制文件呢?
        # 填充0到满足要求为止。
        zeroPad = (448 - (msgLen + 8) % 512) % 512
        zeroPad //= 8
        msg = msg + b'x00' * zeroPad + msgLen.to_bytes(8, byteorder='little')
        # 计算循环轮数,512个为一轮
        msgLen = bitlen(msg)
        iterations = msgLen // 512
        # 初始化变量
        # 算法魔改的第一个点,也是最明显的点
        # A = 0x67452301
        # B = 0xefcdab89
        # C = 0x98badcfe
        # D = 0x10325476
    
        # 魔改版
        A = 0x67552301
        B = 0xEDCDAB89
        C = 0x98BADEFE
        D = 0x16325476
        # MD5的主体就是对abcd进行n次的迭代,所以得有个初始值,可以随便选,也可以用默认的魔数,这个改起来毫无风险,所以大家爱魔改它,甚至改这个都不算魔改。
        # main loop
        for i in range(0, iterations):
            a = A
            b = B
            c = C
            d = D
            block = msg[i * 64:(i + 1) * 64]
            # 明文的处理,顺便调整了一下端序
            M = blockDivide(block, 16)
            # Rounds
            a = FF(a, b, c, d, M[0], 7, SV[0])
            d = FF(d, a, b, c, M[1], 12, SV[1])
            c = FF(c, d, a, b, M[2], 17, SV[2])
            b = FF(b, c, d, a, M[3], 22, SV[3])
            a = FF(a, b, c, d, M[4], 7, SV[4])
            d = FF(d, a, b, c, M[5], 12, SV[5])
            c = FF(c, d, a, b, M[6], 17, SV[6])
            b = FF(b, c, d, a, M[7], 22, SV[7])
            a = FF(a, b, c, d, M[8], 7, SV[8])
            d = FF(d, a, b, c, M[9], 12, SV[9])
            c = FF(c, d, a, b, M[10], 17, SV[10])
            b = FF(b, c, d, a, M[11], 22, SV[11])
            a = FF(a, b, c, d, M[12], 7, SV[12])
            d = FF(d, a, b, c, M[13], 12, SV[13])
            c = FF(c, d, a, b, M[14], 17, SV[14])
            b = FF(b, c, d, a, M[15], 22, SV[15])
    
            a = GG(a, b, c, d, M[1], 5, SV[16])
            d = GG(d, a, b, c, M[6], 9, SV[17])
            c = GG(c, d, a, b, M[11], 14, SV[18])
            b = GG(b, c, d, a, M[0], 20, SV[19])
            a = GG(a, b, c, d, M[5], 5, SV[20])
            d = GG(d, a, b, c, M[10], 9, SV[21])
            c = GG(c, d, a, b, M[15], 14, SV[22])
            b = GG(b, c, d, a, M[4], 20, SV[23])
            a = GG(a, b, c, d, M[9], 5, SV[24])
            d = GG(d, a, b, c, M[14], 9, SV[25])
            c = GG(c, d, a, b, M[3], 14, SV[26])
            b = GG(b, c, d, a, M[8], 20, SV[27])
            a = GG(a, b, c, d, M[13], 5, SV[28])
            d = GG(d, a, b, c, M[2], 9, SV[29])
            c = GG(c, d, a, b, M[7], 14, SV[30])
            b = GG(b, c, d, a, M[12], 20, SV[31])
    
            a = HH(a, b, c, d, M[5], 4, SV[32])
            d = HH(d, a, b, c, M[8], 11, SV[33])
            c = HH(c, d, a, b, M[11], 16, SV[34])
            b = HH(b, c, d, a, M[14], 23, SV[35])
            a = HH(a, b, c, d, M[1], 4, SV[36])
            d = HH(d, a, b, c, M[4], 11, SV[37])
            c = HH(c, d, a, b, M[7], 16, SV[38])
            b = HH(b, c, d, a, M[10], 23, SV[39])
            a = HH(a, b, c, d, M[13], 4, SV[40])
            d = HH(d, a, b, c, M[0], 11, SV[41])
            c = HH(c, d, a, b, M[3], 16, SV[42])
            b = HH(b, c, d, a, M[6], 23, SV[43])
            a = HH(a, b, c, d, M[9], 4, SV[44])
            d = HH(d, a, b, c, M[12], 11, SV[45])
            c = HH(c, d, a, b, M[15], 16, SV[46])
            b = HH(b, c, d, a, M[2], 23, SV[47])
    
            a = II(a, b, c, d, M[0], 6, SV[48])
            d = II(d, a, b, c, M[7], 10, SV[49])
            c = II(c, d, a, b, M[14], 15, SV[50])
            b = II(b, c, d, a, M[5], 21, SV[51])
            a = II(a, b, c, d, M[12], 6, SV[52])
            d = II(d, a, b, c, M[3], 10, SV[53])
            c = II(c, d, a, b, M[10], 15, SV[54])
            b = II(b, c, d, a, M[1], 21, SV[55])
            a = II(a, b, c, d, M[8], 6, SV[56])
            d = II(d, a, b, c, M[15], 10, SV[57])
            c = II(c, d, a, b, M[6], 15, SV[58])
            b = II(b, c, d, a, M[13], 21, SV[59])
            a = II(a, b, c, d, M[4], 6, SV[60])
            d = II(d, a, b, c, M[11], 10, SV[61])
            c = II(c, d, a, b, M[2], 15, SV[62])
            b = II(b, c, d, a, M[9], 21, SV[63])
            A = (A + a) % (2 ** 32)
            B = (B + b) % (2 ** 32)
            C = (C + c) % (2 ** 32)
            D = (D + d) % (2 ** 32)
        result = fmt8(A) + fmt8(B) + fmt8(C) + fmt8(D)
        return result
    
    
    if __name__ == "__main__":
        data = str("hello").encode("UTF-8")
        print("plainText: ", data)
        print("result: ", md5sum(data))
    

    其他资料:
    https://www.cnblogs.com/DeeLMind/p/7581423.html
    https://www.zhihu.com/question/278134292/answer/1139991348

  • 相关阅读:
    iOS 远程推送
    iOS 本地推送
    iOS 循环利用的注意事项
    iOS 通知代理执行代理方式时,代理为nil的解决办法
    iOS SSZipArchive
    iOS PushMebaby
    Objective
    Objective
    Objective
    Objective
  • 原文地址:https://www.cnblogs.com/c-x-a/p/15321081.html
Copyright © 2011-2022 走看看