Como criar um objeto de bytes python de uma longa string hexadecimal?

93

Eu tenho uma longa sequência de dígitos hexadecimais em uma string, como

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

apenas muito mais, vários kilobytes. Existe uma maneira embutida de converter isso em um objeto de bytes em python 2.6 / 3?

recursivo
fonte
4
Observe que as respostas abaixo podem ser semelhantes, mas retornam diferentes tipos de valores. s.decode ('hex') retorna um str, assim como unhexlify (s). bytearray.fromhex (s) retorna um bytearray. Dada a formulação desta pergunta, acho que a grande marca de seleção verde deveria estar em bytearray.fromhex (s), não em s.decode ('hex').
Paul Hoffman
1
Possível duplicata de string hexadecimal para matriz de bytes em python
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Como pode ser uma duplicata de uma pergunta criada 2 anos depois?
recursivo de
1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Uma string de bytes não é uma matriz de bytes. stackoverflow.com/questions/1740696/…
LarsH
@LarsH bastante justo. @ recursivo: a data não é o fator principal: meta.stackexchange.com/questions/147643/…
Ciro Santilli 郝海东 冠状 病 六四 六四 事件 法轮功

Respostas:

101

Funciona em Python 2.7 e superior, incluindo python3:

result = bytearray.fromhex('deadbeef')

Observação: parece haver um bug com a bytearray.fromhex()função no Python 2.6. A documentação de python.org afirma que a função aceita uma string como argumento, mas quando aplicada, o seguinte erro é gerado:

>>> 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
fonte
9
E uma etapa adicional, eu queria uma string de byte (por exemplo, Python 3's b '\ x04 \ xea [...]'), que você pode obter de um bytearray combytes(bytearray.fromhex('deadbeef'))
berto
5
@berto: nesse caso existe uma rota mais direta na forma de binascii.unhexlify().
Martijn Pieters
1
Obrigado, @MartijnPieters, vou tentar
berto
1
Esta resposta não faz o que a pergunta feita. Ele retorna uma matriz mutável de bytes, não um bytestring python. É como retornar um array de strings em vez de uma string.
Mike Martin,
2
@LarsH: esse método não está disponível em versões anteriores do Python 2. Isso não importa mais hoje, mas foi um problema em 2016.
Martijn Pieters
78
result = bytes.fromhex(some_hex_string)
vili
fonte
2
Esta parece ser a maneira mais direta de fazer o que a postagem original está pedindo. Existe uma razão para esta não ser a resposta aceita?
Sebastian Gaweda
O método fromhex () (de bytes e bytearray) também funcionará quando os números hexadecimais são separados por espaços. Muito conveniente!
Klaws de
1
Esta realmente deveria ser a resposta aceita. A resposta aceita atualmente não corresponde à pergunta feita. Ele retorna uma matriz mutável de bytes, não uma sequência de bytes.
Mike Martin,
40

Você pode fazer isso com o codec hexadecimal. ie:

>>> 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
fonte
16
codecs.decode('0a0a0a', 'hex_codec')deve funcionar para 2.xe 3.x :-)
Abbafei
37

Experimente o módulo binascii

from binascii import unhexlify
b = unhexlify(myhexstr)
Crescent Fresh
fonte
9
Duas maneiras de fazer isso no 2.x, três maneiras no 3.x. Tanto para "só há uma maneira de fazer isso" ...
tecnomalógico
Outras duas maneiras são mais 'embutidas', então eu usaria uma delas.
Crescent Fresh
@technomalogical: seu comentário é irrelevante para a resposta; talvez você deva excluí-lo e transformá-lo em um post para comp.lang.python.
tzot de
1
@technomalogical: Concordo com ΤΖΩΤΖΙΟΥ. Além disso, você entendeu errado. A frase correta é: Deve haver uma - e de preferência apenas uma - maneira óbvia de fazer isso.
nosklo
2
Observe que no Python 3.2 (seja por design ou um bug, não tenho certeza) unhexlifyagora não aceita uma string, mas apenas bytes. Muito bobo, na verdade, mas significa que você precisa usarb = unhexlify(bytes(myhexstr, 'utf-8'))
Scott Griffiths
2
import binascii

binascii.a2b_hex(hex_string)

Foi assim que eu fiz.

JustPlayin
fonte
-3
import binascii

binascii.b2a_hex(obj)
Zubair Khalid
fonte