Hexadezimaler String zum Byte-Array in Python

149

Ich habe eine lange Hex-Zeichenfolge, die eine Reihe von Werten unterschiedlichen Typs darstellt. Ich möchte diesen Hex-String in ein Byte-Array konvertieren, damit ich jeden Wert herausschieben und in den richtigen Datentyp konvertieren kann.

Richard
quelle
Wie sieht diese Hex-Zeichenfolge aus?
Khachik

Antworten:

237

Angenommen, Ihre Hex-Zeichenfolge ist so etwas wie

>>> hex_string = "deadbeef"

Konvertieren Sie es in einen String (Python ≤ 2.7):

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

oder seit Python 2.7 und Python 3.0:

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

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

Beachten Sie, dass dies byteseine unveränderliche Version von ist bytearray.

tzot
quelle
27
Wenn jemand nach einem hex string-> bytesObjekt sucht , ergibt sich `bytes.fromhex (" 000102030405060708090A0B0C0D0E0F ")` b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'. Nicht als Antwort posten, da die Frage nach dem Byte-Array fragt, sondern hier posten, da dies der erste Treffer ist, den ich bei der Suche nach Text in Bytes erhalten habe.
Matrixanomalie
@Hubro Eigentlich hex_string.decode("hex")arbeitet an Python 2.7. Ich habe gerade auf meinem getestet Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32.
MewX
@MewX Ich sagte Python 3, nicht Python 2.7
Hubro
3
Beachten Sie, dass bytes.fromhexein Fehler ausgelöst wird, wenn die Eingabezeichenfolge eine ungerade Anzahl von Zeichen enthält: bytes.fromhex("aab")ValueError: non-hexadecimal number found in fromhex() arg at position 3.
24онстантин Ван
143

In bytearray ist eine Funktion integriert, die genau das tut, was Sie beabsichtigen.

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

Es gibt ein Bytearray zurück und liest Hex-Strings mit oder ohne Leerzeichen.

kugg
quelle
4
Die beste Antwort sicher!
Maiku Mori
5
Dies funktioniert in Python 3, hex_string.decode("hex")nicht jedoch.
Eric O Lebigot
15

vorausgesetzt, ich habe es richtig verstanden, sollten Sie nach binascii.unhexlify suchen

import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]
Bruce
quelle
4
Ich bin damit einverstanden, dass dies unhexlifyder effizienteste Weg ist, würde aber vorschlagen, dass b = bytearray(s)dies besser ist als die Verwendung ord. Da Python einen eingebauten Typ nur für Arrays von Bytes hat, bin ich überrascht, dass niemand ihn verwendet
Scott Griffiths
8

Angenommen, Sie haben eine solche Byte-Zeichenfolge

"\ x12 \ x45 \ x00 \ xAB"

und Sie kennen die Anzahl der Bytes und deren Typ. Sie können diesen Ansatz auch verwenden

import struct

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

#val = (18, 69, 43776)

Da ich am Anfang der Formatzeichenfolge Little Endian (mit dem Zeichen '<') angegeben habe, hat die Funktion das Dezimaläquivalent zurückgegeben.

0x12 = 18

0x45 = 69

0xAB00 = 43776

B ist gleich einem Byte (8 Bit) ohne Vorzeichen

H ist gleich zwei Bytes (16 Bit) ohne Vorzeichen

Weitere verfügbare Zeichen und Bytegrößen finden Sie hier

Die Vorteile sind ..

Sie können mehr als ein Byte und das Endian der Werte angeben

Nachteile ..

Sie müssen wirklich die Art und Länge der Daten kennen, mit denen Sie sich befassen

Hovo
quelle
2
Nachteile: Das ist eine Byte-Zeichenfolge, keine Hex-Zeichenfolge, daher ist dies keine Antwort auf die Frage.
Qris
Es ist eine Antwort auf den zweiten Teil der Frage "... damit ich jeden Wert herausschieben und in seinen richtigen Datentyp konvertieren kann".
Rainald62
2

Sie sollten in der Lage sein, eine Zeichenfolge mit den Binärdaten zu erstellen, indem Sie Folgendes verwenden:

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

Dies ist wahrscheinlich nicht der schnellste Weg (viele Zeichenfolgen werden angehängt), aber recht einfach, wenn nur Kern-Python verwendet wird.

entspannen
quelle
2

Sie können das Codecs-Modul in der Python-Standardbibliothek verwenden, d. H.

import codecs

codecs.decode(hexstring, 'hex_codec')
velsim
quelle
-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
quelle
-4

Ein guter Einzeiler ist:

byte_list = map(ord, hex_string)

Dadurch wird jedes Zeichen in der Zeichenfolge durchlaufen und über die Funktion ord () ausgeführt. Nur auf Python 2.6 getestet, nicht sicher über 3.0+.

-Josh

karlw
quelle
perfekt. Arbeiten an Python 2.7
Richard
Klicken Sie auf den Umriss des Häkchens neben dieser Antwort, wenn es die richtige ist! :)
jathanism
1
Dies konvertiert kein Hex - es konvertiert jedes Zeichen einer Zeichenfolge in eine Ganzzahl. Für hex würde jedes Zeichenpaar ein Byte darstellen. Sie könnten genauso gut sagenbyte_list = bytearray(hex_string)
Scott Griffiths