在Python 3中散列文件?

时间:2013-10-13 05:01:34

标签: python hash

在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。

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

3 个答案:

答案 0 :(得分: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")而烦恼。

答案 1 :(得分:6)

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

答案 2 :(得分:0)

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

pip3 install py_essentials

使用这样的模块:

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

查看documentation