Farklı türlerde bir dizi değeri temsil eden uzun bir Hex dizem var. Bu Hex String'i bir bayt dizisine dönüştürmek istiyorum, böylece her değeri dışarı kaydırabilir ve uygun veri türüne dönüştürebilirim.
Yanıtlar:
Onaltılık dizenizin şöyle bir şey olduğunu varsayalım
>>> hex_string = "deadbeef"
>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"
>>> bytes.fromhex(hex_string) # Python ≥ 3
b'\xde\xad\xbe\xef'
>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')
Bunun bytes
değişmez bir sürümü olduğunu unutmayın bytearray
.
string
-> bytes
nesnesini arıyorsa , bu `` bytes.fromhex ("000102030405060708090A0B0C0D0E0F") "sonucunu verir b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
. Soru bayt dizisi istediğinden yanıt olarak gönderilmiyor, ancak hext'i baytlara ararken aldığım ilk hit olduğu için buraya gönderiyorum.
hex_string.decode("hex")
Python 2.7 üzerinde çalışıyor. Ben sadece kendimde test ettim Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
.
bytes.fromhex
Giriş dizesi karakterleri tek sayıda olduğunda bir hata atar: bytes.fromhex("aab")
→ ValueError: non-hexadecimal number found in fromhex() arg at position 3
.
Bytearray'de, niyet ettiğiniz şeyi yapan yerleşik bir işlev vardır.
bytearray.fromhex("de ad be ef 00")
Bir bytearray döndürür ve boşluk ayırıcısı olan veya olmayan onaltılık dizeleri okur.
hex_string.decode("hex")
çalışmaz.
doğru anladıysam, binascii.unhexlify aramalısınız
import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]
unhexlify
gitmenin en verimli yolu olduğuna katılıyorum , ancak bunun b = bytearray(s)
kullanmaktan daha iyi olacağını öneriyorum ord
. Python'un yalnızca bayt dizileri için yerleşik bir türü olduğundan, kimsenin kullanmadığına şaşırdım
Böyle bir bayt dizeniz olduğunu varsayarsak
"\ x12 \ x45 \ x00 \ xAB"
ve bayt miktarını ve türlerini biliyorsunuz, bu yaklaşımı da kullanabilirsiniz
import struct
bytes = '\x12\x45\x00\xAB'
val = struct.unpack('<BBH', bytes)
#val = (18, 69, 43776)
Biçim dizgesinin başında küçük endian'ı ('<' karakterini kullanarak) belirttiğim gibi, işlev ondalık eşdeğerini döndürdü.
0x12 = 18
0x45 = 69
0xAB00 = 43776
B, işaretsiz bir bayta (8 bit) eşittir
H işaretsiz iki bayta (16 bit) eşittir
Daha fazla kullanılabilir karakter ve bayt boyutu burada bulunabilir
Avantajları ...
Birden fazla bayt ve değerlerin sonunu belirtebilirsiniz
Dezavantajları..
İlgilendiğiniz verilerin türünü ve uzunluğunu gerçekten bilmeniz gerekiyor
Aşağıdakiler gibi bir şey kullanarak ikili verileri tutan bir dize oluşturabilmelisiniz:
data = "fef0babe"
bits = ""
for x in xrange(0, len(data), 2)
bits += chr(int(data[x:x+2], 16))
Bu muhtemelen en hızlı yol değil (birçok dize eki), ancak yalnızca çekirdek Python kullanarak oldukça basit.
Sen kullanabilirsiniz Codec'leri modülü yani Python Standart Kütüphane'de
import codecs
codecs.decode(hexstring, 'hex_codec')
def hex2bin(s):
hex_table = ['0000', '0001', '0010', '0011',
'0100', '0101', '0110', '0111',
'1000', '1001', '1010', '1011',
'1100', '1101', '1110', '1111']
bits = ''
for i in range(len(s)):
bits += hex_table[int(s[i], base=16)]
return bits
İyi bir astar:
byte_list = map(ord, hex_string)
Bu, dizedeki her bir karakter üzerinde yineleme yapacak ve onu ord () işlevi aracılığıyla çalıştıracaktır. Yalnızca python 2.6'da test edildi, 3.0+ hakkında çok emin değil.
-Josh
byte_list = bytearray(hex_string)