ฉันมีสตริง Hex ยาวที่แสดงถึงชุดของค่าที่แตกต่างกัน ฉันต้องการแปลง Hex String นี้เป็นอาร์เรย์ไบต์เพื่อให้ฉันสามารถเลื่อนแต่ละค่าออกมาและแปลงเป็นประเภทข้อมูลที่เหมาะสม
ฉันมีสตริง Hex ยาวที่แสดงถึงชุดของค่าที่แตกต่างกัน ฉันต้องการแปลง Hex String นี้เป็นอาร์เรย์ไบต์เพื่อให้ฉันสามารถเลื่อนแต่ละค่าออกมาและแปลงเป็นประเภทข้อมูลที่เหมาะสม
คำตอบ:
สมมติว่าสตริง hex ของคุณเป็นอะไรที่คล้ายกัน
>>> hex_string = "deadbeef"
>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"
>>> bytes.fromhex(hex_string) # Python ≥ 3
b'\xde\xad\xbe\xef'
>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')
ทราบว่าเป็นรุ่นที่ไม่เปลี่ยนรูปของbytes
bytearray
string
-> bytes
วัตถุก็ `bytes.fromhex ( "000102030405060708090A0B0C0D0E0F")` b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
ซึ่งอัตราผลตอบแทน ไม่โพสต์เป็นคำตอบเนื่องจากคำถามถามถึงอาร์เรย์ไบต์ แต่โพสต์ที่นี่เนื่องจากมันเป็นครั้งแรกที่ฉันได้รับเมื่อค้นหา hext to ไบต์
hex_string.decode("hex")
ทำงานบน Python 2.7 Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
ฉันเพียงแค่การทดสอบเกี่ยวกับฉัน
bytes.fromhex
โยนความผิดพลาดเมื่อสายเข้ามีเลขคี่ของตัวอักษร: →bytes.fromhex("aab")
ValueError: non-hexadecimal number found in fromhex() arg at position 3
มีฟังก์ชั่นบิวท์อินในชุดการแสดงผลตามที่คุณต้องการ
bytearray.fromhex("de ad be ef 00")
มันจะส่งกลับ bytearray และจะอ่านสตริง hex ที่มีหรือไม่มีตัวคั่นช่องว่าง
hex_string.decode("hex")
ไม่เป็นเช่นนั้น
หากฉันเข้าใจถูกต้องคุณควรมองหา binascii.unhexlify
import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]
unhexlify
เป็นวิธีที่มีประสิทธิภาพมากที่สุดที่จะไปที่นี่ แต่ขอแนะนำว่าจะเป็นดีกว่าการใช้b = bytearray(s)
ord
เนื่องจาก Python มีประเภทบิวท์อินสำหรับอาร์เรย์จำนวนมากเท่านั้นฉันจึงประหลาดใจที่ไม่มีใครใช้มัน
สมมติว่าคุณมีสตริงไบต์เช่นนั้น
"\ x12 \ x45 \ x00 \ xAB"
และคุณรู้จำนวนไบต์และชนิดของมันที่คุณสามารถใช้วิธีนี้
import struct
bytes = '\x12\x45\x00\xAB'
val = struct.unpack('<BBH', bytes)
#val = (18, 69, 43776)
ตามที่ฉันได้ระบุ endian น้อย (โดยใช้ '<' char) ที่จุดเริ่มต้นของสตริงรูปแบบฟังก์ชันจะคืนค่าทศนิยมเทียบเท่า
0x12 = 18
0x45 = 69
0xAB00 = 43776
B เท่ากับหนึ่งไบต์ (8 บิต) ที่ไม่ได้ลงชื่อ
H เท่ากับสองไบต์ (16 บิต) ที่ไม่ได้ลงชื่อ
ตัวอักษรและขนาดของไบต์ที่พร้อมใช้งานเพิ่มเติมมีอยู่ที่นี่
ข้อดีคือ ..
คุณสามารถระบุมากกว่าหนึ่งไบต์และ endian ของค่า
ข้อเสีย ..
คุณจำเป็นต้องรู้ประเภทและความยาวของข้อมูลที่คุณติดต่อด้วย
คุณควรจะสามารถสร้างสตริงที่เก็บข้อมูลไบนารีโดยใช้สิ่งต่อไปนี้:
data = "fef0babe"
bits = ""
for x in xrange(0, len(data), 2)
bits += chr(int(data[x:x+2], 16))
นี่อาจไม่ใช่วิธีที่เร็วที่สุด (สตริงต่อท้ายจำนวนมาก) แต่ค่อนข้างง่ายโดยใช้ Python หลักเท่านั้น
คุณสามารถใช้โมดูล Codecsใน Python Standard Library เช่น
import codecs
codecs.decode(hexstring, 'hex_codec')
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
ซับหนึ่งที่ดีคือ:
byte_list = map(ord, hex_string)
สิ่งนี้จะวนซ้ำอักขระแต่ละตัวในสตริงและเรียกใช้ผ่านฟังก์ชัน ord () ทดสอบเฉพาะกับงูหลาม 2.6 เท่านั้นไม่แน่ใจเหมือนกันเกี่ยวกับ 3.0+
-Josh
byte_list = bytearray(hex_string)