You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现MD5算法输出与预期不符,应如何定位排查错误?

问题原因&修正方案

核心错误点

  • 错误1:位运算符误用
    计算f函数时错误使用了Python的逻辑运算符and/or,这类运算符仅做逻辑真假判断,不会执行按位与/按位或操作,完全不符合MD5的位运算要求。需要把所有and替换为&,or替换为|。
    错误代码片段:
f = (b1 and c1) or ((~b1) and d1)
...
f = (d1 and b1) or ((~d1) and c1)
...
f = c1 ^ (b1 or (~d1))

修正后写法:

f = (b1 & c1) | ((~b1) & d1)
...
f = (d1 & b1) | ((~d1) & c1)
...
f = c1 ^ (b1 | (~d1))
  • 错误2:最终哈希拼接逻辑错误
    MD5要求将最终的a、b、c、d四个32位寄存器按小端字节序依次拼接得到哈希值,原代码直接通过移位拼接整数的方式,会把每个寄存器的字节序反转,导致最终结果错误。
    可以把返回逻辑修改为将每个寄存器转为小端字节后拼接,再转十六进制即可。

修正后完整可运行代码

import numpy as np
import math

shifts = np.array([
    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
], dtype = np.uint8)

K = np.zeros(64, dtype = np.uint32)
for i in range(64):
    K[i] = int(abs(math.sin(i + 1)) * 2 ** 32)

a0 = np.uint32(0x67452301)
b0 = np.uint32(0xefcdab89)
c0 = np.uint32(0x98badcfe)
d0 = np.uint32(0x10325476)

def md5(message):
    length = len(message)
    padded = message + b'\x80' + b'\0' * ((56 - length - 1) % 64) + (length << 3).to_bytes(8, 'little')
    
    a, b, c, d = a0, b0, c0, d0
    for chunk_no in range(len(padded) // 64):
        a1, b1, c1, d1 = a, b, c, d
        chunk = padded[chunk_no * 64 : (chunk_no + 1) * 64]
        
        M = np.array([int.from_bytes(chunk[j * 4 : (j + 1) * 4], 'little') for j in range(16)], dtype = np.uint32)
        for i in range(64):
            quarter = i >> 4
            if quarter == 0:
                f = (b1 & c1) | ((~b1) & d1)
                g = i
            elif quarter == 1:
                f = (d1 & b1) | ((~d1) & c1)
                g = (5 * i + 1) & 15
            elif quarter == 2:
                f = b1 ^ c1 ^ d1
                g = (3 * i + 5) & 15
            else:
                f = c1 ^ (b1 | (~d1))
                g = (7 * i) & 15
            f = (f + a1 + K[i] + M[g]) & 0xffffffff
            a1, d1, c1, b1 = d1, c1, b1, (b1 + ((f << shifts[i]) | (f >> (32 - shifts[i])))) & 0xffffffff
        a = (a + a1) & 0xffffffff
        b = (b + b1) & 0xffffffff
        c = (c + c1) & 0xffffffff
        d = (d + d1) & 0xffffffff
    a, b, c, d = int(a), int(b), int(c), int(d)
    return b''.join([x.to_bytes(4, 'little') for x in [a, b, c, d]]).hex()

def test():
    data = b''
    digest = md5(data)
    print(f'MD5({data}) = {digest}')
    # 空串测试断言
    assert digest == 'd41d8cd98f00b204e9800998ecf8427e'
    print('空串测试通过')

内容的提问来源于stack exchange,提问作者user2649681

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:39:04