簡體   English   中英

使用hashlib在Python 3中計算文件的md5摘要

[英]Using hashlib to compute md5 digest of a file in Python 3

使用python 2.7,以下代碼計算文件內容的mD5 hexdigest。

(編輯:嗯,不是因為答案已經顯示,我只是這么認為)。

import hashlib

def md5sum(filename):
    f = open(filename, mode='rb')
    d = hashlib.md5()
    for buf in f.read(128):
        d.update(buf)
    return d.hexdigest()

現在,如果我使用python3運行該代碼,則會引發TypeError異常:

    d.update(buf)
TypeError: object supporting the buffer API required

我發現我可以使用python2和python3運行代碼,將其更改為:

def md5sum(filename):
    f = open(filename, mode='r')
    d = hashlib.md5()
    for buf in f.read(128):
        d.update(buf.encode())
    return d.hexdigest()

現在我仍然想知道為什么原始代碼停止工作。 看來,當使用二進制模式修飾符打開文件時,它返回整數而不是編碼為字節的字符串(我說因為type(buf)返回int)。 這種行為是在某處解釋的嗎?

我想你想讓for循環連續調用f.read(128) 這可以使用iter()functools.partial()來完成:

import hashlib
from functools import partial

def md5sum(filename):
    with open(filename, mode='rb') as f:
        d = hashlib.md5()
        for buf in iter(partial(f.read, 128), b''):
            d.update(buf)
    return d.hexdigest()

print(md5sum('utils.py'))
for buf in f.read(128):
  d.update(buf)

..使用文件的前128 個字節值中的每一個順序更新散列。 由於迭代一個bytes會產生int對象,因此會得到以下調用,這些調用會導致您在Python3中遇到錯誤。

d.update(97)
d.update(98)
d.update(99)
d.update(100)

這不是你想要的。

相反,你想要:

def md5sum(filename):
  with open(filename, mode='rb') as f:
    d = hashlib.md5()
    while True:
      buf = f.read(4096) # 128 is smaller than the typical filesystem block
      if not buf:
        break
      d.update(buf)
    return d.hexdigest()

在提問之后,我終於將我的代碼更改為下面的版本(我覺得很容易理解)。 但我可能會將其更改為Raymond Hetting unsing functools.partial建議的版本。

import hashlib

def chunks(filename, chunksize):
    f = open(filename, mode='rb')
    buf = "Let's go"
    while len(buf):
        buf = f.read(chunksize)
        yield buf

def md5sum(filename):
    d = hashlib.md5()
    for buf in chunks(filename, 128):
        d.update(buf)
    return d.hexdigest()

暫無
暫無

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

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