chuỗi thập lục phân thành mảng byte trong python


150

Tôi có một chuỗi Hex dài đại diện cho một loạt các giá trị thuộc các loại khác nhau. Tôi muốn chuyển đổi Chuỗi Hex này thành một mảng byte để tôi có thể chuyển từng giá trị ra và chuyển đổi nó thành kiểu dữ liệu phù hợp.


Chuỗi hex đó trông như thế nào?
khachik

Câu trả lời:


239

Giả sử chuỗi hex của bạn giống như

>>> hex_string = "deadbeef"

Chuyển đổi nó thành một chuỗi (Python 2.7):

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

hoặc kể từ Python 2.7 và Python 3.0:

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

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

Lưu ý rằng đó byteslà một phiên bản bất biến của bytearray.


27
Nếu bất cứ ai đang tìm kiếm đối tượng hex string-> bytes, thì đó là `byte.fromhex (" 000102030405060708090A0B0C0D0E0F ")` mang lại b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'. Không đăng dưới dạng câu trả lời vì câu hỏi yêu cầu mảng byte, nhưng đăng ở đây vì đây là lần truy cập đầu tiên tôi nhận được khi tìm kiếm hext thành byte.
matrixanomaly

@Hubro Thật ra, hex_string.decode("hex")đang làm việc trên Python 2.7. Tôi chỉ thử nghiệm trên của tôi Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32.
MewX

@MewX Tôi đã nói Python 3, không phải Python 2.7
Hubro

3
Lưu ý rằng bytes.fromhexném lỗi khi chuỗi đầu vào có số ký tự lẻ: bytes.fromhex("aab")ValueError: non-hexadecimal number found in fromhex() arg at position 3.
Toàn cảnh

143

Có một chức năng tích hợp trong bytearray thực hiện những gì bạn dự định.

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

Nó trả về một bytearray và nó đọc các chuỗi hex có hoặc không có dấu phân cách.


4
Câu trả lời tốt nhất cho chắc chắn!
Maiku Mori

5
Điều này hoạt động trong Python 3, trong khi hex_string.decode("hex")không.
Eric O Lebigot

15

miễn là tôi hiểu chính xác, bạn nên tìm binascii.unhexlify

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

4
Tôi đồng ý rằng đó unhexlifylà cách hiệu quả nhất để đến đây, nhưng sẽ gợi ý rằng b = bytearray(s)sẽ tốt hơn so với sử dụng ord. Vì Python có một loại tích hợp chỉ dành cho các mảng byte, tôi ngạc nhiên không ai sử dụng nó
Scott Griffiths

8

Giả sử bạn có một chuỗi byte như vậy

"\ x12 \ x45 \ x00 \ xAB"

và bạn biết số lượng byte và loại của chúng, bạn cũng có thể sử dụng phương pháp này

import struct

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

#val = (18, 69, 43776)

Như tôi đã chỉ định endian nhỏ (sử dụng '<' char) ở đầu chuỗi định dạng, hàm trả về số thập phân tương đương.

0x12 = 18

0x45 = 69

0xAB00 = 43776

B bằng một byte (8 bit) không dấu

H bằng hai byte (16 bit) không dấu

Nhiều ký tự có sẵn và kích thước byte có thể được tìm thấy ở đây

Những ưu điểm là..

Bạn có thể chỉ định nhiều hơn một byte và phần cuối của các giá trị

Nhược điểm ..

Bạn thực sự cần biết loại và độ dài dữ liệu mà bạn giao dịch


2
Nhược điểm: đó là chuỗi byte, không phải chuỗi hex, vì vậy đây không phải là câu trả lời cho câu hỏi.
qris 6/2/2015

Đây là câu trả lời cho phần thứ 2 của câu hỏi "... để tôi có thể chuyển từng giá trị ra và chuyển đổi nó thành kiểu dữ liệu phù hợp".
Rainald62

2

Bạn sẽ có thể xây dựng một chuỗi chứa dữ liệu nhị phân bằng cách sử dụng một cái gì đó như:

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

Đây có lẽ không phải là cách nhanh nhất (nhiều chuỗi bổ sung), nhưng khá đơn giản chỉ sử dụng lõi Python.


2

Bạn có thể sử dụng mô-đun Codecs trong Thư viện chuẩn Python, tức là

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

Một lót tốt là:

byte_list = map(ord, hex_string)

Điều này sẽ lặp lại qua từng char trong chuỗi và chạy nó thông qua hàm ord (). Chỉ được thử nghiệm trên python 2.6, không quá chắc chắn về 3.0+.

-Josh


hoàn hảo. Làm việc trên python 2.7
Richard

Nhấp vào phác thảo của dấu kiểm bên cạnh câu trả lời này nếu đó là câu trả lời đúng! :)
jathanism

1
Điều này không chuyển đổi hex - nó chuyển đổi từng ký tự của một chuỗi thành một số nguyên. Đối với hex, mỗi cặp ký tự sẽ đại diện cho một byte. Bạn cũng có thể chỉ cần nóibyte_list = bytearray(hex_string)
Scott Griffiths
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.