Comment créer un objet octets python à partir d'une longue chaîne hexadécimale?

90

J'ai une longue séquence de chiffres hexadécimaux dans une chaîne, telle que

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

seulement beaucoup plus longtemps, plusieurs kilo-octets. Existe-t-il un moyen intégré de convertir cela en un objet octets en python 2.6 / 3?

récursif
la source
4
Notez que les réponses ci-dessous peuvent se ressembler mais qu'elles renvoient différents types de valeurs. s.decode ('hex') renvoie une chaîne, tout comme unhexlify (s). bytearray.fromhex (s) renvoie un bytearray. Compte tenu du libellé de cette question, je pense que la grande coche verte devrait être sur bytearray.fromhex (s), pas sur le décode ('hex').
Paul Hoffman
1
Copie
2
Comment peut-il être le double d'une question créée 2 ans plus tard?
récursif
1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Une chaîne d'octets n'est pas un tableau d'octets. stackoverflow.com/questions/1740696/…
LarsH
@LarsH assez juste. @ recursive: la date n'est pas le facteur principal: meta.stackexchange.com/questions/147643/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

95

Fonctionne avec Python 2.7 et supérieur, y compris python3:

result = bytearray.fromhex('deadbeef')

Remarque: il semble y avoir un bogue avec la bytearray.fromhex()fonction dans Python 2.6. La documentation python.org indique que la fonction accepte une chaîne comme argument, mais lorsqu'elle est appliquée, l'erreur suivante est générée:

>>> 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
la source
9
Et une étape supplémentaire, je voulais une chaîne d'octets (par exemple Python 3 de b « \ x04 \ xea [...] »), que vous pouvez obtenir à partir d' un bytearray avecbytes(bytearray.fromhex('deadbeef'))
Berto
5
@berto: dans ce cas, il existe une route plus directe sous la forme de binascii.unhexlify().
Martijn Pieters
1
Merci, @MartijnPieters, je vais essayer
berto
1
Cette réponse ne fait pas ce que la question a posée. Il renvoie un tableau d'octets modifiables, pas une chaîne d'octets python. C'est comme renvoyer un tableau de chaînes plutôt qu'une chaîne.
Mike Martin
2
@LarsH: cette méthode n'est pas disponible dans les anciennes versions de Python 2. Cela n'a plus d'importance aujourd'hui, mais c'était un problème en 2016.
Martijn Pieters
74
result = bytes.fromhex(some_hex_string)
vili
la source
2
Cela semble être le moyen le plus direct de faire ce que le message original demande. Y a-t-il une raison pour laquelle ce n'est pas la réponse acceptée?
Sebastian Gaweda le
La méthode fromhex () (des octets et bytearray) fonctionnera également lorsque les nombres hexadécimaux sont séparés par des espaces. Très pratique!
Klaws
1
Cela devrait vraiment être la réponse acceptée. La réponse actuellement acceptée ne fait pas ce que la question a posée. Il renvoie un tableau d'octets mutable, pas une chaîne d'octets.
Mike Martin
40

Vous pouvez le faire avec le codec hexadécimal. c'est à dire:

>>> 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
la source
16
codecs.decode('0a0a0a', 'hex_codec')devrait fonctionner pour 2.x et 3.x :-)
Abbafei
37

Essayez le module binascii

from binascii import unhexlify
b = unhexlify(myhexstr)
Croissant frais
la source
9
Deux façons de le faire en 2.x, trois façons en 3.x. Voilà pour "il n'y a qu'une seule façon de le faire" ...
technomalogical
Les deux autres méthodes sont plus «intégrées», donc j'utiliserais en fait l'une d'entre elles.
Crescent Fresh le
@technomalogical: votre commentaire n'a aucun rapport avec la réponse; peut-être devriez-vous le supprimer et le changer en un post en comp.lang.python.
tzot le
1
@technomalogical: Je suis d'accord avec ΤΖΩΤΖΙΟΥ. De plus, vous vous êtes trompé. La phrase correcte est: il devrait y avoir une - et de préférence une seule - façon évidente de le faire.
nosklo
2
Notez que dans Python 3.2 (que ce soit par conception ou par un bogue, je ne suis pas sûr) unhexlifyn'acceptera plus une chaîne, mais uniquement des octets. Assez idiot vraiment, mais cela signifie que vous devez utiliserb = unhexlify(bytes(myhexstr, 'utf-8'))
Scott Griffiths
2
import binascii

binascii.a2b_hex(hex_string)

C'est comme ça que je l'ai fait.

JustPlayin
la source
-3
import binascii

binascii.b2a_hex(obj)
Zubair Khalid
la source