Jak stworzyć obiekt bajtów Pythona z długiego ciągu szesnastkowego?

90

Mam długą sekwencję cyfr szesnastkowych w ciągu, na przykład

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

tylko znacznie dłużej, kilka kilobajtów. Czy istnieje wbudowany sposób konwersji tego na obiekt bajtów w Pythonie 2.6 / 3?

rekurencyjny
źródło
4
Pamiętaj, że poniższe odpowiedzi mogą wyglądać podobnie, ale zwracają różne typy wartości. s.decode ('hex') zwraca str, podobnie jak unhexlify (s). bytearray.fromhex (s) zwraca bytearray. Biorąc pod uwagę brzmienie tego pytania, myślę, że duży zielony znacznik wyboru powinien znajdować się na bytearray.fromhex (s), a nie na s.decode („hex”).
Paul Hoffman,
1
Możliwy duplikat ciągu szesnastkowego do tablicy bajtów w Pythonie
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Jak może być duplikatem pytania utworzonego 2 lata później?
rekurencyjny
1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Ciąg bajtów nie jest tablicą bajtów. stackoverflow.com/questions/1740696/…
LarsH
@LarsH fair. @ recursive: data nie jest głównym czynnikiem: meta.stackexchange.com/questions/147643/ ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

95

Działa w Pythonie 2.7 i nowszych, w tym w Pythonie3:

result = bytearray.fromhex('deadbeef')

Uwaga: wydaje się, że jest błąd w bytearray.fromhex()funkcji w Pythonie 2.6. Dokumentacja python.org stwierdza, że ​​funkcja akceptuje ciąg jako argument, ale po zastosowaniu generowany jest następujący błąd:

>>> bytearray.fromhex('B9 01EF')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: fromhex() argument 1 must be unicode, not str`
Jim Garrison
źródło
9
I jeszcze jeden krok, chciałem ciąg bajtów (np. B '\ x04 \ xea [...]' w Pythonie 3), który można uzyskać z bajtearray za pomocąbytes(bytearray.fromhex('deadbeef'))
berto
5
@berto: w takim przypadku istnieje bardziej bezpośrednia trasa w postaci binascii.unhexlify().
Martijn Pieters
1
Dzięki, @MartijnPieters, dam temu szansę
berto
1
Ta odpowiedź nie odpowiada zadawanemu pytaniu. Zwraca zmienną tablicę bajtów, a nie test bajtów Pythona. To tak, jakby zwracać tablicę ciągów, a nie ciąg.
Mike Martin
2
@LarsH: ta metoda nie jest dostępna w starszych wersjach Pythona 2. Dziś to już nie ma znaczenia, ale był to problem w 2016 roku.
Martijn Pieters
74
result = bytes.fromhex(some_hex_string)
vili
źródło
2
Wydaje się, że jest to najbardziej bezpośredni sposób na zrobienie tego, o co prosi oryginalny post. Czy istnieje powód, dla którego to nie jest akceptowana odpowiedź?
Sebastian Gaweda
Metoda fromhex () (obejmująca zarówno bajty, jak i bytearray) zadziała również, gdy liczby szesnastkowe są oddzielone spacjami. Bardzo wygodne!
Klaws
1
To naprawdę powinna być akceptowana odpowiedź. Aktualnie przyjęta odpowiedź nie odpowiada zadawanemu pytaniu. Zwraca zmienną tablicę bajtów, a nie bajt.
Mike Martin
40

Możesz to zrobić za pomocą kodeka szesnastkowego. to znaczy:

>>> 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'
Brian
źródło
16
codecs.decode('0a0a0a', 'hex_codec')powinien działać dla 2.xi 3.x :-)
Abbafei
37

Wypróbuj moduł binascii

from binascii import unhexlify
b = unhexlify(myhexstr)
Crescent Fresh
źródło
9
Dwa sposoby na zrobienie tego w 2.x, trzy sposoby w 3.x. To tyle, jeśli chodzi o „jest tylko jeden sposób, aby to zrobić” ...
technomalogiczny
Pozostałe dwa sposoby są bardziej „wbudowane”, więc użyłbym jednego z nich.
Crescent Fresh
@technomalogical: Twój komentarz nie ma związku z odpowiedzią; być może powinieneś go usunąć i zamienić na post na comp.lang.python.
tzot
1
@technomalogical: Zgadzam się z ΤΖΩΤΖΙΟΥ. Poza tym źle to zrozumiałeś. Prawidłowe zdanie brzmi: Powinien być jeden - a najlepiej tylko jeden - oczywisty sposób na zrobienie tego.
nosklo
2
Zauważ, że w Pythonie 3.2 (czy to z założenia, czy z błędu nie jestem pewien) unhexlifyteraz nie zaakceptuje łańcucha, ale tylko bajty. Naprawdę dość głupie, ale oznacza to, że musisz użyćb = unhexlify(bytes(myhexstr, 'utf-8'))
Scott Griffiths
2
import binascii

binascii.a2b_hex(hex_string)

Tak to zrobiłem.

JustPlayin
źródło
-3
import binascii

binascii.b2a_hex(obj)
Zubair Khalid
źródło