Як створити байтовий об'єкт python з довгого шістнадцяткового рядка?


91

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

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

лише набагато довше, кілька кілобайт. Чи існує вбудований спосіб перетворити це на байтовий об'єкт у python 2.6 / 3?


4
Зауважте, що наведені нижче відповіді можуть виглядати однаково, але вони повертають різні типи значень. s.decode ('hex') повертає str, як і unhexlify (s). bytearray.fromhex (s) повертає байтовий масив. Враховуючи формулювання цього питання, я думаю, що велика зелена галочка повинна бути на bytearray.fromhex (s), а не на s.decode ('hex').
Пол Хоффман,


2
Як це може бути дублікат запитання, створеного через 2 роки?
рекурсивно

1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Рядок байтів не є байтовим масивом. stackoverflow.com/questions/1740696 / ...
LarsH

@LarsH досить справедливо. @ рекурсивно: дата не є головним фактором: meta.stackexchange.com/questions/147643/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Відповіді:


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
І ще один крок, я хотів байтовий рядок (наприклад, b '\ x04 \ xea [...]' Python 3), який ви можете отримати з байтового масиву за допомогоюbytes(bytearray.fromhex('deadbeef'))
berto

5
@berto: у такому випадку існує більш прямий шлях у формі binascii.unhexlify().
Мартін Пітерс

1
Дякую, @MartijnPieters, я зроблю це
Берто

1
Ця відповідь не відповідає запитанню. Він повертає змінний масив байтів, а не python bytestring. Це як повернення масиву рядків, а не рядка.
Майк Мартін,

2
@LarsH: цей метод недоступний у старих версіях Python 2. Сьогодні це вже не має значення, але це було питання у 2016 році.
Мартін Пітерс

74
result = bytes.fromhex(some_hex_string)

2
Це здається найбільш прямим способом зробити те, про що вимагає оригінальний пост. Чи є причина, що це не прийнята відповідь?
Себастьян Гаведа

Метод fromhex () (як байтів, так і байтового масиву) також буде працювати, коли шістнадцяткові числа розділяються пробілами. Дуже зручно!
Klaws

1
Це справді має бути прийнятою відповіддю. Поточна прийнята відповідь не відповідає запитанню. Він повертає змінний масив байтів, а не тестування байтів.
Mike Martin

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 :-)
Аббафей

37

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

from binascii import unhexlify
b = unhexlify(myhexstr)

9
Два способи зробити це в 2.x, три способи в 3.x. Стільки про те, що "це можна зробити лише одним способом" ...
технологічний

Інші два способи є більш "вбудованими", тому я б насправді використав один із них.
Crescent Fresh

@technomalogical: ваш коментар не має значення для відповіді; можливо, вам слід видалити його та змінити на пост comp.lang.python.
tzot

1
@technomalogical: Я погоджуюсь з ΤΖΩΤΖΙΟΥ. Крім того, ви помилилися. Правильна фраза: Повинен бути один - і бажано лише один - очевидний спосіб зробити це.
nosklo

2
Зауважте, що в Python 3.2 (незалежно від того, за дизайном чи помилкою я не впевнений) unhexlifyтепер не буде прийматися рядок, а лише байти. Насправді досить безглуздо, але це означає, що вам потрібно було б скористатисяb = unhexlify(bytes(myhexstr, 'utf-8'))
Скотт Гріффітс


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.