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?


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


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`

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)

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'

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)

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.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.