在Python 3中散列文件?

Luc*_*ips 5 python hash

在Python 2中,人们可以通过运行来散列字符串:

someText = "a"
hashlib.sha256(someText).hexdigest()
Run Code Online (Sandbox Code Playgroud)

但是在Python 3中,它需要编码:

someText = "a".encode("ascii")
hashlib.sha256(someText).hexdigest()
Run Code Online (Sandbox Code Playgroud)

但是当我用文件尝试这个时:

f = open(fin, "r")
sha = hashlib.sha256()
while True:
    data = f.read(2 ** 20).encode("ascii")
    if not data:
        break
    sha.update(data)
f.close()
Run Code Online (Sandbox Code Playgroud)

我在许多文件上得到这个:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 8: invalid continuation byte
Run Code Online (Sandbox Code Playgroud)

我认为这是因为它是一个二进制文件,可能无法转换为ASCII.

如何在没有此问题的情况下编码文件?

Tim*_*ers 6

在Unix系统上,在Python 2中,二进制文件和文本模式文件之间没有区别,因此打开它们并不重要.

但是在Python 3中,它在每个平台上都很重要. sha256()需要二进制输入,但您以文本模式打开文件.这就是@BrenBam建议你以二进制模式打开文件的原因.

由于您以文本模式打开文件,因此Python 3认为它需要解码文件中的位以将字节转换为Unicode字符串.但是你根本不需要解码,对吧?

然后以二进制模式打开文件,你将读取字节字符串,这是sha256()想要的.

顺便说一下,你的:

someText = "a".encode("ascii")
hashlib.sha256(someText).hexdigest()
Run Code Online (Sandbox Code Playgroud)

可以通过相关方式更轻松地完成:

hashlib.sha256(b"a").hexdigest()
Run Code Online (Sandbox Code Playgroud)

也就是说,直接传递二进制数据,而不是编码Unicode字符串(文字"a"是).


Bre*_*arn 6

尝试使用二进制模式打开文件open(fin, "rb").