web-dev-qa-db-fra.com

Quelle est la bonne façon de convertir des octets en chaîne hexadécimale dans Python 3?

Quelle est la bonne façon de convertir des octets en chaîne hexadécimale dans Python 3?

Je vois les réclamations d'une méthode bytes.hex, de codecs bytes.decode et j'ai essayé autre fonctions possibles du moindre étonnement, mais sans résultat. Je veux juste mes octets comme hex!

178
Matt Joiner

Depuis Python 3.5, ce n’est finalement plus gênant:

>>> b'\xde\xad\xbe\xef'.hex()
'deadbeef'

et inverser:

>>> bytes.fromhex('deadbeef')
b'\xde\xad\xbe\xef'

fonctionne aussi avec le type mutable bytearray.

296
Felix Weis

Utilisez le module binascii:

>>> import binascii
>>> binascii.hexlify('foo'.encode('utf8'))
b'666f6f'
>>> binascii.unhexlify(_).decode('utf8')
'foo'

Voir cette réponse: Python 3.1.1 string to hex

93
Mu Mind

Python a octets à octets codecs standard qui effectuent des transformations pratiques, telles que quoted-printable (correspond à ascii à 7 bits), base64 (correspond à alphanumériques), hex échappé, gzip et compression bz2. Dans Python 2, vous pouvez faire:

b'foo'.encode('hex')

Dans Python 3, str.encode/bytes.decode sont strictement réservés aux conversions d'octets <-> str. Au lieu de cela, vous pouvez faire cela, ce qui fonctionne sur Python 2 et Python 3 ( s/encoder/décoder/g pour l'inverse):

import codecs
codecs.getencoder('hex')(b'foo')[0]

À partir de Python 3.4, il existe une option moins gênante:

codecs.encode(b'foo', 'hex')

Ces codecs divers sont également accessibles dans leurs propres modules (base64, zlib, bz2, uu, quopri, binascii); L'API est moins cohérente, mais pour les codecs de compression, elle offre plus de contrôle.

37
Gabriel
import codecs
codecs.getencoder('hex_codec')(b'foo')[0]

fonctionne dans Python 3.3 (donc "hex_codec" au lieu de "hex").

7
Richard Kiss

La méthode binascii.hexlify() convertira bytes en bytes représentant la chaîne hexadécimale ascii. Cela signifie que chaque octet de l'entrée sera converti en deux caractères ascii. Si vous voulez une vraie str sortie, vous pouvez .decode("ascii") le résultat.

J'ai inclus un extrait qui l'illustre.

import binascii

with open("addressbook.bin", "rb") as f: # or any binary file like '/bin/ls'
    in_bytes = f.read()
    print(in_bytes) # b'\n\x16\n\x04'
    hex_bytes = binascii.hexlify(in_bytes) 
    print(hex_bytes) # b'0a160a04' which is twice as long as in_bytes
    hex_str = hex_bytes.decode("ascii")
    print(hex_str) # 0a160a04

à partir de la chaîne hexagonale "0a160a04" pour revenir à la bytes avec binascii.unhexlify("0a160a04") qui restitue b'\n\x16\n\x04'

5
ecerulm

OK, la réponse suivante dépasse légèrement la portée si vous vous souciez uniquement de Python 3, mais cette question est le premier hit Google, même si vous ne spécifiez pas la version Python. voici une méthode qui fonctionne à la fois Python 2 et Python 3.

J'interprète également la question comme visant la conversion d'octets en type str: c'est-à-dire octets-y sur Python 2 et Unicode-y sur Python 3 .

Compte tenu de cela, la meilleure approche que je connaisse est la suivante:

import six

bytes_to_hex_str = lambda b: ' '.join('%02x' % i for i in six.iterbytes(b))

L'assertion suivante sera vraie pour Python 2 ou Python 3, en supposant que vous n'avez pas activé le unicode_literals future dans Python 2:

assert bytes_to_hex_str(b'jkl') == '6a 6b 6c'

(Ou vous pouvez utiliser ''.join() pour omettre l'espace entre les octets, etc.)

3
Peter

il peut être utilisé le spécificateur de format %x02 qui formate et génère une valeur hexadécimale. Par exemple:

>>> foo = b"tC\xfc}\x05i\x8d\x86\x05\xa5\xb4\xd3]Vd\x9cZ\x92~'6"
>>> res = ""
>>> for b in foo:
...     res += "%02x" % b
... 
>>> print(res)
7443fc7d05698d8605a5b4d35d56649c5a927e2736
2
Arg0s