在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.
如何在没有此问题的情况下编码文件?
在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"是).