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 に答える