шістнадцятковий рядок для байтового масиву в python


150

У мене довга шістнадцятковий рядок, який представляє ряд значень різних типів. Я хочу перетворити цей шістнадцятковий рядок у байтовий масив, щоб я міг змістити кожне значення та перетворити його у відповідний тип даних.


Як виглядає ця шестигранна струна?
хачик

Відповіді:


239

Припустимо, ваш шістнадцятковий рядок щось подібне

>>> 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')

Зауважте, що bytesце незмінна версія bytearray.


27
Якщо хто -то шукає гекса string-> bytesоб'єкт, це `bytes.fromhex (« 000102030405060708090A0B0C0D0E0F »)` , який дає b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'. Не публікація як відповідь, оскільки питання задає байтовий масив, але публікує тут, оскільки це перше звернення, яке я отримав під час пошуку hext до байтів.
матриксаномалія

@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")

Він повертає байт-масив і читає шістнадцяткові рядки з роздільником пробілу або без нього.


4
Найкраща відповідь напевно!
Майку Морі

5
Це працює в Python 3, тоді як hex_string.decode("hex")ні.
Ерік О Лебігот

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)

Як я вказав маленький ендіан (використовуючи знак <<) на початку рядка формату, функція повертала десятковий еквівалент.

0x12 = 18

0x45 = 69

0xAB00 = 43776

B дорівнює одному байту (8 біт) без підпису

H дорівнює двома байтами (16 біт) без підпису

Більше доступних символів та розмірів байтів можна знайти тут

Переваги:

Ви можете вказати більше одного байта і значення ендіана значень

Недоліки ..

Вам дійсно потрібно знати тип і довжину даних, з якими ви маєте справу


2
Недоліки: це байтовий рядок, а не шістнадцятковий рядок, тому це не є відповіддю на питання.
qris

Це відповідь на другу частину питання "... щоб я міг змістити кожне значення і перетворити його у відповідний тип даних".
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 (). Тестується лише на python 2.6, не надто впевнений у 3.0+.

-Джош


досконалий. Робота над python 2.7
Річард

Клацніть контур галочки біля цієї відповіді, якщо вона є правильною! :)
ятанізм

1
Це не конвертує шістнадцятковий - він перетворює кожен символ рядка в ціле число. Для шістнадцятки кожна пара символів буде представляти байт. Ви можете просто сказатиbyte_list = bytearray(hex_string)
Скотт Гріффітс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.