Uzun onaltılık dizeden python bayt nesnesi nasıl oluşturulur?


93

Bir dizede uzun bir onaltılık rakam dizisi var, örneğin

000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44

sadece çok daha uzun, birkaç kilobayt. Python 2.6 / 3'te bunu bir bayt nesnesine dönüştürmenin yerleşik bir yolu var mı?


4
Aşağıdaki yanıtların birbirine benzeyebileceğini ancak farklı türde değerler döndürdüklerini unutmayın. s.decode ('hex'), unhexlify (s) gibi bir str döndürür. bytearray.fromhex (s) bir bytearray döndürür. Bu sorunun ifadesine bakıldığında, büyük yeşil onay işaretinin s.decode ('hex') üzerinde değil bytearray.fromhex (s) üzerinde olması gerektiğini düşünüyorum.
Paul Hoffman


2
Nasıl 2 yıl sonra oluşturulan bir sorunun kopyası olabilir?
yinelemeli

1
@CiroSantilli 郝海东 冠状 病 六四 事件 法轮功 Bir bayt dizisi bir bayt dizisi değildir. stackoverflow.com/questions/1740696/…
LarsH

@LarsH yeterince adil. @ recursive: tarih ana faktör değildir: meta.stackexchange.com/questions/147643/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Yanıtlar:


101

Python3 dahil olmak üzere Python 2.7 ve üzeri sürümlerde çalışır:

result = bytearray.fromhex('deadbeef')

Not:bytearray.fromhex() Python 2.6'daki fonksiyonda bir hata var gibi görünüyor . Python.org dokümantasyonu, işlevin bir dizeyi argüman olarak kabul ettiğini, ancak uygulandığında aşağıdaki hata atıldığını belirtir:

>>> 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
Ve bir ek adım, bir byte dizesi istedim (ör. Python 3'ün b '\ x04 \ xea [...]'), ki bunu bir bytearray ilebytes(bytearray.fromhex('deadbeef'))
berto

5
@berto: bu durumda şeklinde daha doğrudan bir yol var binascii.unhexlify().
Martijn Pieters

1
Teşekkürler @MartijnPieters, buna bir şans vereceğim
berto

1
Bu cevap, sorunun sorulduğu şeyi yapmaz. Değiştirilebilir bir bayt dizisi döndürür, bir python bytestring'i değil. Bu, bir dizeden çok bir dizi döndürmeye benzer.
Mike Martin

2
@LarsH: bu yöntem daha eski Python 2 sürümlerinde mevcut değildir. Bu bugün artık önemli değil, ancak 2016'daki bir sorundu.
Martijn Pieters

78
result = bytes.fromhex(some_hex_string)

2
Bu, orijinal gönderinin istediğini yapmanın en doğrudan yolu gibi görünüyor. Bunun kabul edilen cevap olmamasının bir nedeni var mı?
Sebastian Gaweda

Fromhex () yöntemi (hem bayt hem de bytearray), onaltılık sayılar boşluklarla ayrıldığında da çalışır. Çok uygun!
Klaws

1
Bu gerçekten kabul edilen cevap olmalı. Mevcut kabul edilen cevap, sorunun sorulduğu şeyi yapmıyor. Bir bayt testi değil, değiştirilebilir bir bayt dizisi döndürür.
Mike Martin

40

Bunu hex codec bileşeni ile yapabilirsiniz. yani:

>>> 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 ve 3.x için çalışmalıdır :-)
Abbafei

37

Binascii modülünü deneyin

from binascii import unhexlify
b = unhexlify(myhexstr)

9
Bunu 2.x'te yapmanın iki yolu, 3.x'te üç yol. "Bunu yapmanın tek bir yolu var" için çok fazla ...
technomalogical

Diğer iki yol daha 'yerleşiktir', bu yüzden bunlardan birini gerçekten kullanırdım.
Crescent Fresh

@technomalogical: yorumunuz yanıtla alakasız; belki onu silmeli ve comp.lang.python için bir gönderi olarak değiştirmelisiniz.
tzot

1
@technomalogical: ΤΖΩΤΖΙΟΥ ile aynı fikirdeyim. Ayrıca yanlış anlamışsın. Doğru ifade şudur: Bunu yapmanın bir - ve tercihen sadece bir - açık yolu olmalıdır.
nosklo

2
Python 3.2'de (ister tasarımdan ister hatadan emin değilim) unhexlifyartık bir dizeyi kabul etmeyeceğine, yalnızca baytları kabul edeceğine dikkat edin. Oldukça aptalca, ama kullanmanız gerektiği anlamına geliyorb = unhexlify(bytes(myhexstr, 'utf-8'))
Scott Griffiths


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.