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!
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
.
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
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.
import codecs
codecs.getencoder('hex_codec')(b'foo')[0]
fonctionne dans Python 3.3 (donc "hex_codec" au lieu de "hex").
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'
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.)
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