string heksadesimal ke byte array dalam python

150

Saya memiliki string Hex panjang yang mewakili serangkaian nilai dari berbagai jenis. Saya ingin mengubah String Hex ini menjadi array byte sehingga saya bisa menggeser setiap nilai keluar dan mengubahnya menjadi tipe data yang tepat.

Richard
sumber
Bagaimana rupa string hex itu?
khachik

Jawaban:

239

Misalkan string hex Anda adalah sesuatu seperti

>>> hex_string = "deadbeef"

Konversikan ke string (Python ≤ 2.7):

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

atau sejak Python 2.7 dan Python 3.0:

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

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

Perhatikan bahwa itu bytesadalah versi yang tidak berubah dari bytearray.

tzot
sumber
27
Jika ada yang mencari objek hex string-> bytes, `bytes.fromhex (" 000102030405060708090A0B0C0D0E0F ")` yang menghasilkan b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'. Tidak memposting sebagai jawaban karena pertanyaan meminta byte array, tetapi memposting di sini karena itu adalah hit pertama yang saya dapatkan ketika mencari hext ke byte.
matrixanomaly
@Hubro Sebenarnya, hex_string.decode("hex")sedang bekerja pada Python 2.7. Saya baru saja menguji pada saya Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32.
MewX
@MewX Saya mengatakan Python 3, bukan Python 2.7
Hubro
3
Perhatikan bahwa bytes.fromhexmelempar kesalahan ketika string input memiliki jumlah karakter ganjil: bytes.fromhex("aab")ValueError: non-hexadecimal number found in fromhex() arg at position 3.
Константин Ван
143

Ada fungsi bawaan di bytearray yang melakukan apa yang Anda inginkan.

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

Ini mengembalikan bytearray dan membaca string hex dengan atau tanpa pemisah ruang.

Kugg
sumber
4
Jawaban terbaik pasti!
Maiku Mori
5
Ini berfungsi di Python 3, sedangkan hex_string.decode("hex")tidak.
Eric O Lebigot
15

asalkan saya mengerti dengan benar, Anda harus mencari binascii.unhexlify

import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]
Bruce
sumber
4
Saya setuju itu unhexlifyadalah cara paling efisien untuk pergi ke sini, tetapi akan menyarankan itu b = bytearray(s)akan menjadi lebih baik daripada menggunakan ord. Karena Python memiliki tipe bawaan hanya untuk array byte, saya terkejut tidak ada yang menggunakannya
Scott Griffiths
8

Dengan asumsi Anda memiliki string byte seperti itu

"\ x12 \ x45 \ x00 \ xAB"

dan Anda tahu jumlah byte dan tipenya, Anda juga dapat menggunakan pendekatan ini

import struct

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

#val = (18, 69, 43776)

Seperti yang saya tentukan endian kecil (menggunakan char '<') pada awal string format fungsi mengembalikan setara desimal.

0x12 = 18

0x45 = 69

0xAB00 = 43776

B sama dengan satu byte (8 bit) yang tidak ditandatangani

H sama dengan dua byte (16 bit) yang tidak ditandatangani

Lebih banyak karakter dan ukuran byte yang tersedia dapat ditemukan di sini

Keuntungannya adalah ..

Anda dapat menentukan lebih dari satu byte dan endian nilai

Kekurangan ..

Anda benar-benar perlu mengetahui jenis dan panjang data yang Anda hadapi

Hovo
sumber
2
Kekurangan: itu adalah string byte, bukan string hex, jadi ini bukan jawaban untuk pertanyaan itu.
qris
Ini adalah jawaban untuk pertanyaan ke-2 dari pertanyaan "... sehingga saya dapat mengubah setiap nilai dan mengubahnya menjadi tipe data yang tepat".
Rainald62
2

Anda harus bisa membuat string yang menyimpan data biner menggunakan sesuatu seperti:

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

Ini mungkin bukan cara tercepat (banyak string ditambahkan), tetapi cukup sederhana dengan hanya menggunakan Python inti.

beristirahat
sumber
2

Anda dapat menggunakan modul Codec di Python Standard Library, yaitu

import codecs

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

Satu liner yang bagus adalah:

byte_list = map(ord, hex_string)

Ini akan mengulangi setiap karakter dalam string dan menjalankannya melalui fungsi ord (). Hanya diuji pada python 2.6, tidak terlalu yakin tentang 3.0+.

Astaga

karlw
sumber
sempurna. Bekerja pada python 2.7
Richard
Klik garis besar tanda centang di sebelah jawaban ini jika jawaban itu benar! :)
jathanism
1
Ini tidak mengonversi hex - ia mengonversi setiap karakter string menjadi integer. Untuk hex, setiap pasangan karakter akan mewakili satu byte. Anda mungkin juga mengatakanbyte_list = bytearray(hex_string)
Scott Griffiths