stringa esadecimale per array di byte in Python


150

Ho una lunga stringa esadecimale che rappresenta una serie di valori di diversi tipi. Vorrei convertire questa stringa esadecimale in una matrice di byte in modo da poter spostare ogni valore fuori e convertirlo nel suo tipo di dati corretto.


Come appare quella stringa esadecimale?
Khachik,

Risposte:


239

Supponiamo che la tua stringa esadecimale sia simile

>>> hex_string = "deadbeef"

Converti in una stringa (Python ≤ 2.7):

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

o da Python 2.7 e Python 3.0:

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

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

Nota che bytesè una versione immutabile di bytearray.


27
Se qualcuno sta cercando l' oggetto hex string-> bytes, è `bytes.fromhex (" 000102030405060708090A0B0C0D0E0F ")` che produce b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'. Non pubblicare come risposta poiché la domanda richiede array di byte, ma pubblicare qui poiché è il primo hit che ho ottenuto durante la ricerca di byte in byte.
matrixanomaly

@Hubro In realtà, hex_string.decode("hex")sta lavorando su Python 2.7. Ho appena provato il mio Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32.
MewX,

@MewX Ho detto Python 3, non Python 2.7
Hubro il

3
Si noti che bytes.fromhexgenera un errore quando la stringa di input ha un numero dispari di caratteri: bytes.fromhex("aab")ValueError: non-hexadecimal number found in fromhex() arg at position 3.
Константин Ван

143

C'è una funzione integrata in bytearray che fa ciò che intendi.

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

Restituisce un bytearray e legge stringhe esadecimali con o senza separatore di spazi.


4
La migliore risposta di sicuro!
Maiku Mori,

5
Questo funziona in Python 3, mentre hex_string.decode("hex")non lo è.
Eric O Lebigot,

15

se ho capito bene, dovresti cercare binascii.unhexlify

import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]

4
Sono d'accordo che unhexlifysia il modo più efficiente per andare qui, ma suggerirei che b = bytearray(s)sarebbe meglio che usare ord. Dato che Python ha un tipo incorporato solo per array di byte, sono sorpreso che nessuno lo stia usando
Scott Griffiths

8

Supponendo che tu abbia una stringa di byte in questo modo

"\ X12 \ x45 \ x00 \ XAB"

e conosci la quantità di byte e il loro tipo puoi anche usare questo approccio

import struct

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

#val = (18, 69, 43776)

Come ho specificato little endian (usando il carattere '<') all'inizio della stringa di formato, la funzione ha restituito l'equivalente decimale.

0x12 = 18

0x45 = 69

0xAB00 = 43776

B è uguale a un byte (8 bit) senza segno

H è uguale a due byte (16 bit) senza segno

Altri caratteri disponibili e dimensioni dei byte sono disponibili qui

I vantaggi sono ...

È possibile specificare più di un byte e l'endian dei valori

Svantaggi ..

Devi davvero conoscere il tipo e la lunghezza dei dati con cui hai a che fare


2
Svantaggi: questa è una stringa di byte, non una stringa esadecimale, quindi questa non è una risposta alla domanda.
Qris,

È una risposta alla seconda parte della domanda "... in modo che io possa spostare ogni valore fuori e convertirlo nel suo tipo di dati corretto".
Rainald62

2

Dovresti essere in grado di creare una stringa contenente i dati binari usando qualcosa del tipo:

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

Questo probabilmente non è il modo più veloce (molte stringhe vengono aggiunte), ma piuttosto semplice usando solo il core Python.


2

Puoi usare il modulo Codecs nella libreria standard di Python, ad es

import codecs

codecs.decode(hexstring, 'hex_codec')

-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

-4

Una buona fodera è:

byte_list = map(ord, hex_string)

Questo eseguirà l'iterazione su ogni carattere nella stringa e lo eseguirà attraverso la funzione ord (). Testato solo su Python 2.6, non troppo sicuro su 3.0+.

-Josh


Perfetto. Lavorando su Python 2.7
Richard,

Fai clic sul contorno del segno di spunta accanto a questa risposta se è quello giusto! :)
jatanismo

1
Questo non converte esadecimale: converte ogni carattere di una stringa in un numero intero. Per hex ogni coppia di caratteri rappresenterebbe un byte. Potresti anche solo direbyte_list = bytearray(hex_string)
Scott Griffiths,
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.