6

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

someText = "a"
hashlib.sha256(someText).hexdigest()

但在 Python 3 中,需要对其进行编码:

someText = "a".encode("ascii")
hashlib.sha256(someText).hexdigest()

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

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()

我在很多文件上都得到了这个:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 8: invalid continuation byte

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

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

4

3 回答 3

6

在 Unix 系统上,在 Python 2 中,二进制文件和文本模式文件之间没有区别,因此无论您如何打开它们都无关紧要。

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

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

然后以二进制模式打开文件,您将改为读取字节字符串,这正是我们sha256()想要的。

顺便说一句,您的:

someText = "a".encode("ascii")
hashlib.sha256(someText).hexdigest()

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

hashlib.sha256(b"a").hexdigest()

也就是说,直接将二进制数据传递给它,而不用费心编码一个 Unicode 字符串(即字面"a"量)。

于 2013-10-13T05:15:07.057 回答
6

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

于 2013-10-13T05:17:26.950 回答
0

我编写了一个模块,该模块能够使用不同的算法散列大文件。

pip3 install py_essentials

像这样使用模块:

from py_essentials import hashing as hs
hash = hs.fileChecksum("path/to/the/file.txt", "sha256")

看看文档

于 2018-02-12T00:52:38.500 回答