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?


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,


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

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`

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)

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'

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)

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


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.