Как создать объект байтов python из длинной шестнадцатеричной строки?

91

У меня есть длинная последовательность шестнадцатеричных цифр в строке, например

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

только намного длиннее, несколько килобайт. Есть ли встроенный способ преобразовать это в объект байтов в python 2.6 / 3?

рекурсивный
источник
4
Обратите внимание, что приведенные ниже ответы могут выглядеть одинаково, но возвращают разные типы значений. s.decode ('hex') возвращает строку, как и unhexlify (s). bytearray.fromhex (s) возвращает массив байтов. Учитывая формулировку этого вопроса, я думаю, что большая зеленая галочка должна быть на bytearray.fromhex (s), а не на s.decode ('hex').
Пол Хоффман
1
Возможный дубликат шестнадцатеричной строки в байтовый массив в python
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Как это может быть дубликат вопроса, созданного двумя годами позже?
рекурсивный
1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Строка байтов не является массивом байтов. stackoverflow.com/questions/1740696/…
Ларш
@LarsH достаточно честно. @ рекурсивный: дата не является главным фактором: meta.stackexchange.com/questions/147643/…
Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

Ответы:

96

Работает в Python 2.7 и выше, включая python3:

result = bytearray.fromhex('deadbeef')

Примечание. Похоже, что это ошибка bytearray.fromhex()функции в Python 2.6. В документации python.org указано, что функция принимает строку в качестве аргумента, но при ее применении выдается следующая ошибка:

>>> bytearray.fromhex('B9 01EF')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: fromhex() argument 1 must be unicode, not str`
Джим Гаррисон
источник
9
И еще один шаг, мне нужна байтовая строка (например, Python 3 b '\ x04 \ xea [...]'), которую вы можете получить из bytes(bytearray.fromhex('deadbeef'))
байтового массива
5
@berto: в этом случае есть более прямой маршрут в виде binascii.unhexlify().
Мартейн Питерс
1
Спасибо, @MartijnPieters, я
попробую
1
Этот ответ не соответствует заданному вопросу. Он возвращает изменяемый массив байтов, а не строку байтов Python. Это похоже на возврат массива строк, а не строки.
Майк Мартин,
2
@LarsH: этот метод недоступен в старых версиях Python 2. Сегодня это уже не имеет значения, но это было проблемой в 2016 году.
Мартейн Питерс
74
result = bytes.fromhex(some_hex_string)
вили
источник
2
Это кажется наиболее прямым способом сделать то, о чем просит исходный пост. Есть ли причина, по которой это не принятый ответ?
Себастьян Гаведа
Метод fromhex () (как bytes, так и bytearray) также будет работать, когда шестнадцатеричные числа разделены пробелами. Очень удобно!
Klaws
1
Это действительно должен быть принятый ответ. Текущий принятый ответ не соответствует заданному вопросу. Он возвращает изменяемый массив байтов, а не строку байтов.
Майк Мартин
40

Вы можете сделать это с помощью шестнадцатеричного кодека. то есть:

>>> s='000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44'
>>> s.decode('hex')
'\x00\x00\x00\x00\x00\x00HB@\xfa\x06=\xe5\xd0\xb7D\xad\xbe\xd6:\x81\xfa\xea9\x00\x00\xc8B\x86@\xa4=P\x05\xbdD'
Брайан
источник
16
codecs.decode('0a0a0a', 'hex_codec')должно работать для 2.x и 3.x :-)
Abbafei
37

Попробуйте модуль binascii

from binascii import unhexlify
b = unhexlify(myhexstr)
Crescent Fresh
источник
9
Два способа сделать это в 2.x, три способа в 3.x. Вот и все, что «есть только один способ сделать это» ...
technomalogical
Другие два способа более «встроены», поэтому я бы на самом деле использовал один из них.
Crescent Fresh
@technomalogical: ваш комментарий не имеет отношения к ответу; возможно, вам следует удалить его и превратить в сообщение на comp.lang.python.
цот
1
@technomalogical: Я согласен с ΤΖΩΤΖΙΟΥ. Кроме того, вы ошиблись. Правильная фраза: должен быть один - а желательно только один - очевидный способ сделать это.
носкло
2
Обратите внимание, что в Python 3.2 (по дизайну или из-за ошибки я не уверен) unhexlifyтеперь не будет принимать строку, а будут только байты. На самом деле довольно глупо, но это означает, что вам нужно будет использоватьb = unhexlify(bytes(myhexstr, 'utf-8'))
Скотт Гриффитс
2
import binascii

binascii.a2b_hex(hex_string)

Вот как я это сделал.

JustPlayin
источник
-3
import binascii

binascii.b2a_hex(obj)
Зубаир Халид
источник