¿Cómo crear un objeto de bytes de Python a partir de una cadena hexadecimal larga?

90

Tengo una secuencia larga de dígitos hexadecimales en una cadena, como

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

solo mucho más, varios kilobytes. ¿Hay alguna forma incorporada de convertir esto en un objeto de bytes en Python 2.6 / 3?

recursivo
fuente
4
Tenga en cuenta que las respuestas a continuación pueden parecerse pero devuelven diferentes tipos de valores. s.decode ('hex') devuelve una cadena, al igual que unhexlify (s). bytearray.fromhex (s) devuelve un bytearray. Dada la redacción de esta pregunta, creo que la gran marca de verificación verde debería estar en bytearray.fromhex (s), no en s.decode ('hex').
Paul Hoffman
1
Posible duplicado de cadena hexadecimal a matriz de bytes en Python
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
¿Cómo puede ser un duplicado de una pregunta creada 2 años después?
recursivo
1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Una cadena de bytes no es una matriz de bytes. stackoverflow.com/questions/1740696/…
LarsH
@LarsH bastante justo. @ recursive: la fecha no es el factor principal: meta.stackexchange.com/questions/147643/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

95

Funciona en Python 2.7 y superior, incluido python3:

result = bytearray.fromhex('deadbeef')

Nota: parece haber un error con la bytearray.fromhex()función en Python 2.6. La documentación de python.org indica que la función acepta una cadena como argumento, pero cuando se aplica, se produce el siguiente error:

>>> bytearray.fromhex('B9 01EF')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: fromhex() argument 1 must be unicode, not str`
Jim Garrison
fuente
9
Y un paso adicional, quería una cadena de bytes (por ejemplo, Python 3's b '\ x04 \ xea [...]'), que puede obtener de un bytearray conbytes(bytearray.fromhex('deadbeef'))
berto
5
@berto: en ese caso hay una ruta más directa en forma de binascii.unhexlify().
Martijn Pieters
1
Gracias, @MartijnPieters, lo intentaré
berto
1
Esta respuesta no hace lo que hizo la pregunta. Devuelve una matriz mutable de bytes, no una cadena de bytes de Python. Eso es como devolver una matriz de cadenas en lugar de una cadena.
Mike Martin
2
@LarsH: ese método no está disponible en versiones anteriores de Python 2. Eso ya no importa hoy, pero fue un problema en 2016.
Martijn Pieters
74
result = bytes.fromhex(some_hex_string)
vili
fuente
2
Esta parece ser la forma más directa de hacer lo que pide la publicación original. ¿Hay alguna razón por la que esta no es la respuesta aceptada?
Sebastian Gaweda
El método fromhex () (de bytes y bytearray) también funcionará cuando los números hexadecimales estén separados por espacios. ¡Muy conveniente!
Klaws
1
Esta realmente debería ser la respuesta aceptada. La respuesta aceptada actual no hace lo que se planteó la pregunta. Devuelve una matriz mutable de bytes, no una cadena de bytes.
Mike Martin
40

Puede hacer esto con el códec hexadecimal. es decir:

>>> s='000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44'
>>> s.decode('hex')
'\x00\x00\x00\x00\x00\x00HB@\xfa\x06=\xe5\xd0\xb7D\xad\xbe\xd6:\x81\xfa\xea9\x00\x00\xc8B\x86@\xa4=P\x05\xbdD'
Brian
fuente
16
codecs.decode('0a0a0a', 'hex_codec')debería funcionar para 2.xy 3.x :-)
Abbafei
37

Prueba el módulo binascii

from binascii import unhexlify
b = unhexlify(myhexstr)
Creciente fresco
fuente
9
Dos formas de hacerlo en 2.x, tres formas en 3.x. Demasiado para "solo hay una manera de hacerlo" ...
tecnomagico
Otras dos formas son más "integradas", por lo que en realidad usaría una de esas.
Crescent Fresh
@technomalogical: su comentario es irrelevante para la respuesta; tal vez debería eliminarlo y convertirlo en una publicación en comp.lang.python.
tzot
1
@technomalogical: Estoy de acuerdo con ΤΖΩΤΖΙΟΥ. Además, te equivocaste. La frase correcta es: debe haber una, y preferiblemente solo una, forma obvia de hacerlo.
nosklo
2
Tenga en cuenta que en Python 3.2 (ya sea por diseño o un error, no estoy seguro) unhexlifyahora no aceptará una cadena, sino solo bytes. Realmente bastante tonto, pero significa que necesitarías usarlob = unhexlify(bytes(myhexstr, 'utf-8'))
Scott Griffiths
2
import binascii

binascii.a2b_hex(hex_string)

Así es como lo hice.

JustPlayin
fuente
-3
import binascii

binascii.b2a_hex(obj)
Zubair Khalid
fuente