計算にhashlibを使用すると、PythonでファイルのダイジェストMD5 3

StackOverflow https://stackoverflow.com/questions/7829499

  •  27-10-2019
  •  | 
  •  

質問

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()
元のコードが動作停止した理由今、私はまだだろうか。バイナリモードを使用してファイルを開くとき修飾子、それは整数の代わりのバイトとしてエンコードされた文字列(私はタイプ(BUF)はint型を返すためと言う)を返すようです。この動作は、どこかに説明しますか?

役に立ちましたか?

解決

私はあなたが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()

私は最終的に質問をした後、(私が理解しやすい見つけること)以下のバージョンに私のコードを変更しました。しかし、私はおそらくレイモンド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帰属
所属していません StackOverflow
scroll top