Come creare un oggetto byte Python da una stringa esadecimale lunga?


90

Ho una lunga sequenza di cifre esadecimali in una stringa, come

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

solo molto più a lungo, diversi kilobyte. Esiste un modo integrato per convertirlo in un oggetto byte in Python 2.6 / 3?


4
Tieni presente che le risposte seguenti possono sembrare uguali ma restituiscono diversi tipi di valori. s.decode ('hex') restituisce uno str, così come unhexlify (s). bytearray.fromhex (s) restituisce un bytearray. Data la formulazione di questa domanda, penso che il grande segno di spunta verde dovrebbe essere su bytearray.fromhex (s), non su s.decode ('hex').
Paul Hoffman


2
Come può essere un duplicato di una domanda creata 2 anni dopo?
ricorsivo

1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Una stringa di byte non è un array di byte. stackoverflow.com/questions/1740696/...
Larsh

@ LarsH abbastanza giusto. @ ricorsivo: la data non è il fattore principale: meta.stackexchange.com/questions/147643/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Risposte:


95

Funziona in Python 2.7 e versioni successive, incluso python3:

result = bytearray.fromhex('deadbeef')

Nota: sembra che ci sia un bug con la bytearray.fromhex()funzione in Python 2.6. La documentazione di python.org afferma che la funzione accetta una stringa come argomento, ma quando viene applicata, viene generato il seguente errore:

>>> 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 un ulteriore passaggio, volevo una stringa di byte (ad esempio b '\ x04 \ xea [...]' di Python 3), che puoi ottenere da un bytearray conbytes(bytearray.fromhex('deadbeef'))
berto

5
@berto: in quel caso c'è un percorso più diretto sotto forma di binascii.unhexlify().
Martijn Pieters

1
Grazie, @MartijnPieters, darò che un colpo
berto

1
Questa risposta non fa quello che la domanda posta. Restituisce un array mutevole di byte, non una stringa di byte Python. È come restituire un array di stringhe piuttosto che una stringa.
Mike Martin,

2
@LarsH: questo metodo non è disponibile nelle versioni precedenti di Python 2. Oggi non ha più importanza, ma è stato un problema nel 2016.
Martijn Pieters

74
result = bytes.fromhex(some_hex_string)

2
Questo sembra il modo più diretto per fare ciò che chiede il post originale. C'è una ragione per cui questa non è la risposta accettata?
Sebastian Gaweda

Il metodo fromhex () (di entrambi i byte e bytearray) funzionerà anche quando i numeri esadecimali sono separati da spazi. Molto conveniente!
Klaws

1
Questa dovrebbe essere davvero la risposta accettata. L'attuale risposta accettata non fa ciò che la domanda posta. Restituisce un array mutabile di byte, non una stringa di byte.
Mike Martin,

40

Puoi farlo con il codec esadecimale. cioè:

>>> 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')dovrebbe funzionare per 2.xe 3.x :-)
Abbafei

37

Prova il modulo binascii

from binascii import unhexlify
b = unhexlify(myhexstr)

9
Due modi per farlo in 2.x, tre modi per 3.x. Questo per quanto riguarda "c'è solo un modo per farlo" ...
tecnomalogico

Altri due modi sono più "integrati", quindi ne userei uno.
Crescent Fresh

@technomalogical: il tuo commento è irrilevante per la risposta; forse dovresti eliminarlo e trasformarlo in un post in comp.lang.python.
tzot

1
@technomalogical: sono d'accordo con ΤΖΩΤΖΙΟΥ. Inoltre, hai sbagliato. La frase corretta è: dovrebbe esserci un modo ovvio, e preferibilmente solo uno, per farlo.
nosklo

2
Nota che in Python 3.2 (sia per progettazione che per un bug non sono sicuro) unhexlifyora non accetterà una stringa, ma solo byte. Davvero abbastanza sciocco, ma significa che dovresti usareb = unhexlify(bytes(myhexstr, 'utf-8'))
Scott Griffiths

2
import binascii

binascii.a2b_hex(hex_string)

È così che l'ho fatto.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.