python'da onaltılık dize bayt dizisine


156

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.


Bu onaltılık ip nasıl görünüyor?
khachik

Yanıtlar:


251

Onaltılık dizenizin şöyle bir şey olduğunu varsayalım

>>> hex_string = "deadbeef"

Bir dizgeye dönüştürün (Python ≤ 2.7):

>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"

veya Python 2.7 ve Python 3.0'dan beri:

>>> bytes.fromhex(hex_string)  # Python ≥ 3
b'\xde\xad\xbe\xef'

>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')

Bunun bytesdeğişmez bir sürümü olduğunu unutmayın bytearray.


29
Herhangi biri hex string-> bytesnesnesini 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.
matrixanomaly

@Hubro Aslında, 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.
MewX

@MewX Python 2.7 değil Python 3 dedim
Hubro

3
Notbytes.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.
Константин Ван

146

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.


4
Kesinlikle en iyi cevap!
Maiku Mori

7
Bu Python 3'te çalışır, oysa hex_string.decode("hex")çalışmaz.
Eric O Lebigot

16

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]

4
Buraya unhexlifygitmenin 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
Scott Griffiths

8

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


2
Dezavantajlar: bu bir onaltılık dizge değil, bir bayt dizesidir, dolayısıyla bu sorunun cevabı değildir.
qris

Bu, "... her bir değeri dışarı kaydırıp uygun veri türüne dönüştürebilmem için" sorunun 2. kısmının cevabıdır.
Rainald62

2

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.



-3
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

-4

İ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


mükemmel. Python 2.7 üzerinde çalışıyor
Richard

Doğru cevapsa, bu cevabın yanındaki onay işaretinin ana hatlarını tıklayın! :)
jathanism

1
Bu hex'i dönüştürmez - bir dizenin her karakterini bir tam sayıya dönüştürür. Hex için her karakter çifti bir baytı temsil eder. byte_list = bytearray(hex_string)
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.