web-dev-qa-db-ja.com

'utf-8'コーデックはバイト0x80をデコードできません

BVLCでトレーニングされたモデルをダウンロードしようとしていますが、このエラーが発生します

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 110: invalid start byte

私はそれが次の機能のためだと思います( 完全なコード

  # Closure-d function for checking SHA1.
  def model_checks_out(filename=model_filename, sha1=frontmatter['sha1']):
      with open(filename, 'r') as f:
          return hashlib.sha1(f.read()).hexdigest() == sha1

これを修正する方法はありますか?

9
Ehab AlBadawy

UTF-8でエンコードされていないファイルを開いていますが、システムのデフォルトのエンコードはUTF-8に設定されています。

SHA1ハッシュを計算しているため、代わりにbinaryとしてデータを読み取る必要があります。 hashlib関数では、バイト単位で渡す必要があります。

_with open(filename, 'rb') as f:
    return hashlib.sha1(f.read()).hexdigest() == sha1
_

ファイルモードでbが追加されていることに注意してください。

open() documentation を参照してください:

modeは、ファイルを開くモードを指定するオプションの文字列です。デフォルトは_'r'_で、これはテキストモードで読み取り用に開くことを意味します。 [...]テキストモードで、encodingが指定されていない場合使用されるエンコーディングはプラットフォームに依存します:locale.getpreferredencoding(False)は現在のロケールエンコーディングを取得するために呼び出されます。 (生バイトの読み取りと書き込みには、バイナリモードを使用し、encodingを指定しないままにします。)

および hashlibモジュールのドキュメント から:

Update()メソッドを使用して、このオブジェクトにバイトのようなオブジェクト(通常はバイト)をフィードできます。

15
Martijn Pieters

ファイルをバイナリモードで開くように指定しなかったため、f.read()はファイルをUTF-8でエンコードされたテキストファイルとして読み取ろうとしますが、機能していないようです。しかし、stringsではなくbytesのハッシュを使用するため、エンコーディングが何であるか、またはファイルがテキストであるかどうかは関係ありません。 、それをバイナリファイルとして読み込みます。

>>> with open("test.h5.bz2","r") as f: print(hashlib.sha1(f.read()).hexdigest())
Traceback (most recent call last):
  File "<ipython-input-3-fdba09d5390b>", line 1, in <module>
    with open("test.h5.bz2","r") as f: print(hashlib.sha1(f.read()).hexdigest())
  File "/home/dsm/sys/pys/Python-3.5.1-bin/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in position 10: invalid start byte

だが

>>> with open("test.h5.bz2","rb") as f: print(hashlib.sha1(f.read()).hexdigest())
21bd89480061c80f347e34594e71c6943ca11325
5
DSM

ドキュメントにもsrcコードにもヒントが1つもないので、理由はわかりませんが、b char(バイナリの推測)を使用しても完全に機能します(tf-version:1.1.0):

image_data = tf.gfile.FastGFile(filename, 'rb').read()

詳細については、チェックアウト:gfile

2
4F2E4A2E