2011-07-08 26 views
83

¿Cuál es la forma correcta de convertir bytes a una cadena hexadecimal en Python 3?¿Cuál es la forma correcta de convertir bytes a una cadena hexadecimal en Python 3?

veo reclamaciones de un método bytes.hex, bytes.decode codecs, y han intentado other posibles funciones de mínima sorpresa sin resultado. ¡Solo quiero mis bytes como hex!

+0

"sin resultado"? ¿Qué problemas ** ** específicos o errores está obteniendo? Por favor muestra el código y los errores. –

+0

Posible duplicado de http://stackoverflow.com/questions/2340319/python-3-1-1-string-to-hex –

Respuesta

75

utilizar el módulo binascii:

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

Ver esta respuesta: Python 3.1.1 string to hex

+6

Esto es bueno. Alucinante es que puedes convertir hexadecimal en bytes usando bytes.fromhex (hex_str), pero no puedes convertir bytes en hexadecimal usando bytes.tohex() - ¿cuál es la racionalidad en esto? – nagylzs

+1

Supongo que la relación entre bytes y hexadecimal no es una propiedad de ninguno (lo que no explica por qué fromhex está ahí). Parece que no fue solo un descuido, sino algo sobre lo que se discutió: http://bugs.python.org/issue3532#msg70950. P: ¿Le haría daño tener el método tohex del objeto bytes para realizar esta tarea también? A: IMO, sí, lo haría. Complica el código y aleja el enfoque del enfoque adecuado para la conversión de datos (es decir, funciones, no métodos). –

+2

¿Esto realmente responde la pregunta? No devuelve un hex 'str' sino un' bytes'. Sé que OP parece estar contento con la respuesta, pero no será mejor expandir esta respuesta para incluir '.decode (" ascii ")' también para convertirla en una "cadena" – ecerulm

27

Python tiene bytes-a-bytes standard codecs que realizan transformaciones convenientes como citado imprimible (encaja en 7 bits ASCII), base 64 (se adapta a alfanuméricos), hex escape, compresión gzip y bz2. En Python 2, usted podría hacer:

b'foo'.encode('hex') 

en Python 3, str.encode/bytes.decode son estrictamente para bytes < -> str conversiones. En su lugar, usted puede hacer esto, que funciona a través de Python 2 y Python 3 (s/codificación/decodificación/g para la inversa):

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

A partir de Python 3.4, hay una opción menos incómoda:

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

Estos códecs misc también son accesibles dentro de sus propios módulos (base64, zlib, bz2, uu, quopri, binascii); la API es menos consistente, pero para códecs de compresión ofrece más control.

+1

usando python 3.3: 'LookupError: codificación desconocida: hex' –

+0

@JanusTroelsen: prueba ['hex_codec'] (http://stackoverflow.com/a/22465079/4279). O simplemente use 'binascii.hexlify (b'foo ')' directamente – jfs

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

obras en Python 3.3 (por lo que "hex_codec" en lugar de "hex").

+0

Quizás de manera interesante, en Python 3.4 "hex" o "hex_codec" funciona bien. –

3

El método binascii.hexlify() convertirá bytes en un bytes que representa la cadena hexagonal ascii. Eso significa que cada byte en la entrada se convertirá en dos caracteres ascii. Si quiere un verdadero str, entonces puede .decode("ascii") el resultado.

Incluí un fragmento que lo ilustra.

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 

de la cadena hexadecimal "0a160a04" que puede volver a la bytes con binascii.unhexlify("0a160a04") la que da vuelta b'\n\x16\n\x04'

118

Como Python 3.5 esto es, finalmente, ya no es incómoda:

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

e inverso:

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

funciona también con el tipo mutable bytearray.

+1

Referencia: https://docs.python.org/3/library/stdtypes.html#bytes.hex – minexew

0

Si desea convertir b '\ x61' a 97 o '0x61', puede intentar esto:

[python3.5] 
>>>from struct import * 
>>>temp=unpack('B',b'\x61')[0] ## convert bytes to unsigned int 
97 
>>>hex(temp) ##convert int to string which is hexadecimal expression 
'0x61' 

Referencia: https://docs.python.org/3.5/library/struct.html

Cuestiones relacionadas