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


91

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

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

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


4
Обратите внимание, что приведенные ниже ответы могут выглядеть одинаково, но возвращают разные типы значений. s.decode ('hex') возвращает строку, как и unhexlify (s). bytearray.fromhex (s) возвращает массив байтов. Учитывая формулировку этого вопроса, я думаю, что большая зеленая галочка должна быть на bytearray.fromhex (s), а не на s.decode ('hex').
Пол Хоффман


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)

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'))
Скотт Гриффитс


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.