簡體   English   中英

奇怪的python的hashlib.md5行為,每次都有不同的哈希

[英]Strange python's hashlib.md5 behavior, different hash each time

我在嘗試計算字符串的md5哈希值時遇到了一些非常奇怪的行為。 如果我傳遞的是串聯結果,則返回的哈希值總是錯誤的(且不同)。 獲得真正的哈希的唯一方法是傳遞創建后未進行任何修改的字符串。

Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> m = hashlib.md5() 
>>> a1 = "stack"
>>> a2 = "overflow"
>>> a3 = a1 + a2
>>> a4 = str(a1 + a2)
>>> m.update("stackoverflow")
>>> m.hexdigest()
'73868cb1848a216984dca1b6b0ee37bc' //actuall hash
>>> m.update(a1 + a2)
>>> m.hexdigest()
'458b7358b9e0c3f561957b96e543c5a8'
>>> m.update(a3)
>>> m.hexdigest()
'65b0e62d4ff2d91e111ecc8f27f0e8f5'
>>> m.update(a4)
>>> m.hexdigest()
'60c3ae3dd9a2095340b2e024194bad3c'
>>> m.update(a1 + a2)
>>> m.hexdigest()
'acd4e14145d34dcb10af785badf8e73e'
>>> m.update(a1 + a2)
>>> m.hexdigest()
'03c06ca09faa26166f1096db02272b11'
>>> a1 + a2 == a1 + a2
True
>>> a1 + a2 == a3
True
>>> a3 == a4
True

我想念什么嗎?

您所缺少的是hash.update() 不會替換散列數據 您將不斷更新哈希對象,因此您將獲得串聯字符串的哈希值。 hashlib.hash.update()文檔中

使用字符串arg更新哈希對象。 重復調用等效於將所有參數串聯在一起的單個調用: m.update(a) ; m.update(b)等同於m.update(a+b)

大膽強調我的。

因此,您不會獲取單個'stackoverflow'字符串的哈希,而是首先獲取'stackoverflow' ,然后是'stackoverflowstackoverflow' ,然后是'stackoverflowstackoverflowstackoverflow'等的哈希,每次附加另一個'stackoverflow'創建更長的哈希值,更長的字符串。 這些較長的字符串都不與原始的較短的字符串相等,因此它們的哈希也不太可能相等。

為新字符串創建一個對象,而不是:

>>> import hashlib
>>> m = hashlib.md5()
>>> m.update('stack' + 'overflow')
>>> m.hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'
>>> m = hashlib.md5()   # **new** hash object
>>> m.update('stackoverflow')
>>> m.hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'
>>> m = hashlib.md5()     # new object again
>>> m.update('stack')     # add the string in pieces, part 1
>>> m.update('overflow')  # and part 2
>>> m.hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'

您可以通過發送串聯數據來輕松產生“錯誤”哈希:

>>> m = hashlib.md5()
>>> m.update('stackoverflowstackoverflow')
>>> m.hexdigest()
'458b7358b9e0c3f561957b96e543c5a8'
>>> m = hashlib.md5()
>>> m.update('stackoverflowstackoverflowstackoverflow')
>>> m.hexdigest()
'65b0e62d4ff2d91e111ecc8f27f0e8f5'
>>> m = hashlib.md5()
>>> m.update('stackoverflow' * 4)
>>> m.hexdigest()
'60c3ae3dd9a2095340b2e024194bad3c'

請注意,您還可以將第一個字符串傳遞給md5()函數:

>>> hashlib.md5('stackoverflow').hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'

通常,僅當您正在分塊處理數據時才使用hash.update()方法(例如逐行讀取文件或從套接字讀取數據塊),並且不想將所有數據都保存在其中。一次記憶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM