重复使用hashlib.md5对象为何对相同字符串计算出不同哈希值?
问题解析:为什么替换第二个字符串后,第三个哈希结果不同?
嘿,这个问题我刚接触hashlib的时候也踩过一模一样的坑——你忽略了哈希对象的累积更新特性!
核心原因:update()是追加而非独立计算
hashlib里的哈希对象(比如你用的md5Hash)是状态化的:每次调用update(),它会把传入的字符串追加到之前的输入数据末尾,然后计算整个拼接后数据的哈希值,而不是单独计算当前字符串的哈希。
用你的代码举个直观的例子:
第一段代码的三次
update,等价于计算字符串'CoconutsApplesOranges'的哈希,每次的hexdigest()是当前累积数据的结果:- 第一次:仅
'Coconuts'的哈希 →0e8f7761bb8cd94c83e15ea7e720852a - 第二次:
'Coconuts'+'Apples'的哈希 →217f2e2059306ab14286d8808f687abb - 第三次:
'Coconuts'+'Apples'+'Oranges'的哈希 →4ce7cfed2e8cb204baeba9c471d48f07
- 第一次:仅
第二段代码替换了第二个字符串,三次
update等价于计算'CoconutsBananasOranges'的哈希:- 第一次:仅
'Coconuts'的哈希(和第一段一致)→0e8f7761bb8cd94c83e15ea7e720852a - 第二次:
'Coconuts'+'Bananas'的哈希 →a82bf69bf25207f2846c015654ae68d1 - 第三次:
'Coconuts'+'Bananas'+'Oranges'的哈希 →47dba619e1f3eaa8e8a01ab93c79781e
- 第一次:仅
所以第三个结果不同,是因为它是前面所有字符串拼接后的整体哈希,而不是单独'Oranges'的哈希——哈希算法确实对相同字符串返回一致结果,但这里你两次的输入根本不是同一个字符串呀!
验证与修正方法
验证:直接计算拼接字符串的哈希
你可以直接计算拼接后的字符串哈希,和第三次update的结果对比,完全一致:
import hashlib # 验证第一段的第三次结果 md5_full_1 = hashlib.md5() md5_full_1.update(b'CoconutsApplesOranges') print(md5_full_1.hexdigest()) # 输出:4ce7cfed2e8cb204baeba9c471d48f07 # 验证第二段的第三次结果 md5_full_2 = hashlib.md5() md5_full_2.update(b'CoconutsBananasOranges') print(md5_full_2.hexdigest()) # 输出:47dba619e1f3eaa8e8a01ab93c79781e
修正:如果想单独计算每个字符串的哈希
如果你希望每次都得到当前字符串的独立哈希,需要每次创建新的哈希对象,而不是复用同一个:
import hashlib # 单独计算'Coconuts'的哈希 md5_coco = hashlib.md5() md5_coco.update(b'Coconuts') print(md5_coco.hexdigest()) # 0e8f7761bb8cd94c83e15ea7e720852a # 单独计算'Apples'/'Bananas'的哈希 md5_apple = hashlib.md5() md5_apple.update(b'Apples') print(md5_apple.hexdigest()) # 单独计算'Oranges'的哈希(两次代码里这个结果会完全相同) md5_orange = hashlib.md5() md5_orange.update(b'Oranges') print(md5_orange.hexdigest())
内容的提问来源于stack exchange,提问作者Linus Choudhury
相关产品推荐
相关产品推荐

