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.


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.


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.


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]

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


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.


2

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

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

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


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.