web-dev-qa-db-fra.com

Le codec 'utf-8' ne peut pas décoder l'octet 0x80

J'essaie de télécharger un modèle formé par BVLC et je suis coincé avec cette erreur

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

Je pense que c'est à cause de la fonction suivante ( code complet )

  # 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

Une idée de comment résoudre ce problème?

9
Ehab AlBadawy

Vous ouvrez un fichier qui n'est pas encodé en UTF-8, tandis que l'encodage par défaut pour votre système est défini sur UTF-8.

Puisque vous calculez un hachage SHA1, vous devez plutôt lire les données en tant que binaire . Les fonctions hashlib nécessitent que vous passiez des octets:

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

Notez l'ajout de b en mode fichier.

Voir la documentation open() :

mode est une chaîne facultative qui spécifie le mode dans lequel le fichier est ouvert. La valeur par défaut est 'r', Ce qui signifie ouvert pour la lecture en mode texte. [...] En mode texte, si le codage n'est pas spécifié l'encodage utilisé dépend de la plate-forme: locale.getpreferredencoding(False) est appelé pour obtenir l'encodage local actuel. (Pour lire et écrire des octets bruts, utilisez le mode binaire et laissez l'encodage non spécifié.)

et de la documentation du module hashlib :

Vous pouvez maintenant alimenter cet objet avec des objets de type octets (normalement des octets) à l'aide de la méthode update ().

15
Martijn Pieters

Vous n'avez pas spécifié d'ouvrir le fichier en mode binaire, donc f.read() essaie de lire le fichier en tant que fichier texte encodé en UTF-8, ce qui ne semble pas fonctionner. Mais puisque nous prenons le hachage de octets, pas de chaînes, peu importe le codage, ou même si le fichier est du texte: ouvrez-le simplement , puis lisez-le, sous forme de fichier binaire.

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

mais

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

Puisqu'il n'y a pas un seul indice dans la documentation ni le code src, je n'ai aucune idée pourquoi, mais l'utilisation du b char (je suppose pour le binaire) fonctionne totalement (tf-version: 1.1.0):

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

Pour plus d'informations, consultez: gfile

2
4F2E4A2E