สตริงเลขฐานสิบหกเป็นอาร์เรย์ไบต์ในไพ ธ อน


150

ฉันมีสตริง Hex ยาวที่แสดงถึงชุดของค่าที่แตกต่างกัน ฉันต้องการแปลง Hex String นี้เป็นอาร์เรย์ไบต์เพื่อให้ฉันสามารถเลื่อนแต่ละค่าออกมาและแปลงเป็นประเภทข้อมูลที่เหมาะสม


สตริง hex นั้นมีลักษณะอย่างไร
khachik

คำตอบ:


239

สมมติว่าสตริง hex ของคุณเป็นอะไรที่คล้ายกัน

>>> hex_string = "deadbeef"

แปลงเป็นสตริง (Python ≤ 2.7):

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

หรือตั้งแต่ Python 2.7 และ Python 3.0:

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

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

ทราบว่าเป็นรุ่นที่ไม่เปลี่ยนรูปของbytesbytearray


27
หากใครที่กำลังมองหาฐานสิบหกstring-> bytesวัตถุก็ `bytes.fromhex ( "000102030405060708090A0B0C0D0E0F")` b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'ซึ่งอัตราผลตอบแทน ไม่โพสต์เป็นคำตอบเนื่องจากคำถามถามถึงอาร์เรย์ไบต์ แต่โพสต์ที่นี่เนื่องจากมันเป็นครั้งแรกที่ฉันได้รับเมื่อค้นหา hext to ไบต์
matrixanomaly

@Hubro จริงแล้ว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ฉันเพียงแค่การทดสอบเกี่ยวกับฉัน
MewX

@MewX ฉันพูด Python 3 ไม่ใช่ Python 2.7
Hubro

3
หมายเหตุว่าbytes.fromhexโยนความผิดพลาดเมื่อสายเข้ามีเลขคี่ของตัวอักษร: →bytes.fromhex("aab") ValueError: non-hexadecimal number found in fromhex() arg at position 3
КонстантинВан

143

มีฟังก์ชั่นบิวท์อินในชุดการแสดงผลตามที่คุณต้องการ

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

มันจะส่งกลับ bytearray และจะอ่านสตริง hex ที่มีหรือไม่มีตัวคั่นช่องว่าง


4
คำตอบที่ดีที่สุดแน่นอน!
Maiku Mori

5
สิ่งนี้ใช้ได้ใน Python 3 โดยที่hex_string.decode("hex")ไม่เป็นเช่นนั้น
Eric O Lebigot

15

หากฉันเข้าใจถูกต้องคุณควรมองหา binascii.unhexlify

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

4
ผมยอมรับว่าunhexlifyเป็นวิธีที่มีประสิทธิภาพมากที่สุดที่จะไปที่นี่ แต่ขอแนะนำว่าจะเป็นดีกว่าการใช้b = bytearray(s) ordเนื่องจาก Python มีประเภทบิวท์อินสำหรับอาร์เรย์จำนวนมากเท่านั้นฉันจึงประหลาดใจที่ไม่มีใครใช้มัน
Scott Griffiths

8

สมมติว่าคุณมีสตริงไบต์เช่นนั้น

"\ 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 ของค่า

ข้อเสีย ..

คุณจำเป็นต้องรู้ประเภทและความยาวของข้อมูลที่คุณติดต่อด้วย


2
ข้อเสีย: นั่นคือสตริงไบต์ไม่ใช่สตริง hex ดังนั้นนี่ไม่ใช่คำตอบสำหรับคำถาม
qris

มันเป็นคำตอบของส่วนที่ 2 ของคำถาม "... เพื่อให้ฉันสามารถเลื่อนแต่ละค่าออกมาและแปลงเป็นประเภทข้อมูลที่เหมาะสม"
Rainald62

2

คุณควรจะสามารถสร้างสตริงที่เก็บข้อมูลไบนารีโดยใช้สิ่งต่อไปนี้:

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

นี่อาจไม่ใช่วิธีที่เร็วที่สุด (สตริงต่อท้ายจำนวนมาก) แต่ค่อนข้างง่ายโดยใช้ Python หลักเท่านั้น



-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

ซับหนึ่งที่ดีคือ:

byte_list = map(ord, hex_string)

สิ่งนี้จะวนซ้ำอักขระแต่ละตัวในสตริงและเรียกใช้ผ่านฟังก์ชัน ord () ทดสอบเฉพาะกับงูหลาม 2.6 เท่านั้นไม่แน่ใจเหมือนกันเกี่ยวกับ 3.0+

-Josh


สมบูรณ์ ทำงานกับ python 2.7
Richard

คลิกโครงร่างของเครื่องหมายถูกที่อยู่ถัดจากคำตอบนี้หากเป็นคำตอบที่ถูกต้อง! :)
jathanism

1
สิ่งนี้ไม่แปลงฐานสิบหก - แปลงอักขระแต่ละตัวของสตริงเป็นจำนวนเต็ม สำหรับฐานสิบหกแต่ละคู่ของตัวละครจะเป็นตัวแทนของไบต์ คุณอาจพูดได้เช่นกันbyte_list = bytearray(hex_string)
Scott Griffiths
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.