chaîne hexadécimale en tableau d'octets en python

150

J'ai une longue chaîne hexadécimale qui représente une série de valeurs de différents types. Je souhaite convertir cette chaîne hexadécimale en un tableau d'octets afin de pouvoir décaler chaque valeur et la convertir dans son type de données approprié.

Richard
la source
À quoi ressemble cette chaîne hexadécimale?
khachik

Réponses:

239

Supposons que votre chaîne hexadécimale ressemble à quelque chose comme

>>> hex_string = "deadbeef"

Convertissez-le en chaîne (Python ≤ 2.7):

>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"

ou depuis Python 2.7 et Python 3.0:

>>> bytes.fromhex(hex_string)  # Python ≥ 3
b'\xde\xad\xbe\xef'

>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')

Notez qu'il bytess'agit d'une version immuable de bytearray.

tzot
la source
27
Si quelqu'un cherche un objet hex string-> bytes, c'est `bytes.fromhex (" 000102030405060708090A0B0C0D0E0F ")` qui donne b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'. Ne pas poster comme réponse puisque la question demande un tableau d'octets, mais poster ici car c'est le premier hit que j'ai obtenu lors de la recherche de hext en octets.
matrixanomaly
@Hubro En fait, hex_string.decode("hex")travaille sur Python 2.7. Je viens de tester sur mon Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32.
MewX
@MewX J'ai dit Python 3, pas Python 2.7
Hubro
3
Notez que bytes.fromhexgénère une erreur lorsque la chaîne d'entrée a un nombre impair de caractères: bytes.fromhex("aab")ValueError: non-hexadecimal number found in fromhex() arg at position 3.
Константин Ван
143

Il existe une fonction intégrée dans bytearray qui fait ce que vous voulez.

bytearray.fromhex("de ad be ef 00")

Il renvoie un bytearray et lit les chaînes hexadécimales avec ou sans séparateur d'espace.

Kugg
la source
4
La meilleure réponse à coup sûr!
Maiku Mori
5
Cela fonctionne dans Python 3, alors que ce hex_string.decode("hex")n'est pas le cas.
Eric O Lebigot
15

à condition d'avoir bien compris, vous devriez chercher binascii.unhexlify

import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]
Bruce
la source
4
Je conviens que unhexlifyc'est la façon la plus efficace de procéder ici, mais je dirais que ce b = bytearray(s)serait mieux que d'utiliser ord. Comme Python a un type intégré juste pour les tableaux d'octets, je suis surpris que personne ne l'utilise
Scott Griffiths
8

En supposant que vous ayez une chaîne d'octets comme celle-ci

"\ x12 \ x45 \ x00 \ xAB"

et vous connaissez la quantité d'octets et leur type, vous pouvez également utiliser cette approche

import struct

bytes = '\x12\x45\x00\xAB'
val = struct.unpack('<BBH', bytes)

#val = (18, 69, 43776)

Comme j'ai spécifié little endian (en utilisant le caractère «<») au début de la chaîne de format, la fonction a renvoyé l'équivalent décimal.

0x12 = 18

0x45 = 69

0xAB00 = 43776

B est égal à un octet (8 bits) non signé

H est égal à deux octets (16 bits) non signés

Plus de caractères disponibles et de tailles d'octets peuvent être trouvés ici

Les avantages sont ..

Vous pouvez spécifier plus d'un octet et l'extrémité des valeurs

Désavantages..

Vous devez vraiment connaître le type et la longueur des données avec lesquelles vous traitez

Hovo
la source
2
Inconvénients: c'est une chaîne d'octets, pas une chaîne hexadécimale, donc ce n'est pas une réponse à la question.
qris
C'est une réponse à la 2ème partie de la question "... pour que je puisse décaler chaque valeur et la convertir dans son type de données approprié".
Rainald62
2

Vous devriez pouvoir construire une chaîne contenant les données binaires en utilisant quelque chose comme:

data = "fef0babe"
bits = ""
for x in xrange(0, len(data), 2)
  bits += chr(int(data[x:x+2], 16))

Ce n'est probablement pas le moyen le plus rapide (beaucoup d'ajouts de chaînes), mais assez simple en utilisant uniquement le noyau Python.

se détendre
la source
2

Vous pouvez utiliser le module Codecs dans la bibliothèque standard Python, c'est-à-dire

import codecs

codecs.decode(hexstring, 'hex_codec')
Velsim
la source
-3
def hex2bin(s):
    hex_table = ['0000', '0001', '0010', '0011',
                 '0100', '0101', '0110', '0111',
                 '1000', '1001', '1010', '1011',
                 '1100', '1101', '1110', '1111']
    bits = ''
    for i in range(len(s)):
        bits += hex_table[int(s[i], base=16)]
    return bits
Dmitry Sobolev
la source
-4

Une bonne doublure est:

byte_list = map(ord, hex_string)

Cela itérera sur chaque caractère de la chaîne et l'exécutera via la fonction ord (). Uniquement testé sur python 2.6, pas trop sûr de 3.0+.

-Josh

Karlw
la source
parfait. Travailler sur python 2.7
Richard
Cliquez sur le contour de la coche à côté de cette réponse si c'est la bonne! :)
jathanism
1
Cela ne convertit pas hexadécimal - il convertit chaque caractère d'une chaîne en entier. Pour hexadécimal, chaque paire de caractères représenterait un octet. Vous pourriez aussi bien direbyte_list = bytearray(hex_string)
Scott Griffiths