Pythonの16進文字列からバイト配列へ


150

さまざまなタイプの一連の値を表す長い16進文字列があります。この16進文字列をバイト配列に変換して、各値をシフトアウトして適切なデータ型に変換できるようにしたいと思います。


その16進文字列はどのように見えますか?
khachik

回答:


239

あなたの16進文字列が次のようなものであるとしましょう

>>> hex_string = "deadbeef"

それを文字列に変換します(Python≤2.7):

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

またはPython 2.7およびPython 3.0以降:

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

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

bytesの不変バージョンですbytearray


27
誰かがhex- string> bytesオブジェクトを探している場合は、 `bytes.fromhex(" 000102030405060708090A0B0C0D0E0F ")`となり、が生成されb'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'ます。質問はバイト配列を要求するため、回答として投稿するのではなく、バイトの次数を検索したときに最初にヒットしたため、ここに投稿します。
マトリックス異常2015

@Hubro実際にhex_string.decode("hex")は、Python 2.7に取り組んでいます。でテストしましたPython 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
MewX 2017年

@MewX私はPython 2.7ではなくPython 3と言った
Hubro

3
bytes.fromhex入力文字列の文字数が奇数の場合、エラーがスローされることに注意しくださいbytes.fromhex("aab")ValueError: non-hexadecimal number found in fromhex() arg at position 3
КонстантинВан

143

意図したことを行う組み込み関数がbytearrayにあります。

bytearray.fromhex("de ad be ef 00")

バイト配列を返し、スペース区切りの有無にかかわらず16進文字列を読み取ります。


4
確かにベストアンサー!
森まいく2014

5
これはPython 3で機能しますhex_string.decode("hex")が、機能しません。
Eric O Lebigot、2015

15

私が正しく理解していれば、binascii.unhexlifyを探す必要があります

import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]

4
これunhexlifyが最も効率的な方法であることに同意しますが、b = bytearray(s)を使用するよりも優れていることをお勧めしordます。Pythonにはバイトの配列専用の組み込み型があるので、誰もそれを使用していないことに驚いています
Scott Griffiths

8

あなたがそのようなバイト文字列を持っていると仮定します

「\ x12 \ x45 \ x00 \ xAB」

バイト数とそのタイプがわかっている場合は、このアプローチも使用できます

import struct

bytes = '\x12\x45\x00\xAB'
val = struct.unpack('<BBH', bytes)

#val = (18, 69, 43776)

フォーマット文字列の先頭にリトルエンディアン( '<'文字を使用)を指定したため、関数は同等の10進数を返しました。

0x12 = 18

0x45 = 69

0xAB00 = 43776

Bは、1バイト(8ビット)の符号なしに等しい

Hは符号なしの2バイト(16ビット)に等しい

より多くの利用可能な文字とバイトサイズはここにあります

利点は..

複数のバイトと値のエンディアンを指定できます

短所...

処理するデータのタイプと長さを本当に知る必要がある


2
欠点:16進文字列ではなくバイト文字列であるため、これは質問に対する回答ではありません。
qris

これは、「各値をシフトアウトして適切なデータ型に変換できるように」という質問の2番目の部分に対する回答です。
Rainald62

2

次のようなものを使用して、バイナリデータを保持する文字列を構築できるはずです。

data = "fef0babe"
bits = ""
for x in xrange(0, len(data), 2)
  bits += chr(int(data[x:x+2], 16))

これはおそらく最速の方法(多くの文字列を追加する方法)ではありませんが、コアPythonのみを使用すると非常に簡単です。



-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

良いワンライナーは:

byte_list = map(ord, hex_string)

これにより、文字列の各文字が反復処理され、ord()関数で実行されます。Python 2.6でのみテストされています。3.0以降についてはあまり確信が持てません。

-ジョシュ


完璧。Python 2.7への取り組み
Richard

正しい場合は、この回答の横にあるチェックマークの概要をクリックしてください。:)
ヤタニズム

1
これは16進数を変換しません-文字列の各文字を整数に変換します。16進数の場合、文字の各ペアは1バイトを表します。ちょうど言うかもしれませんbyte_list = bytearray(hex_string)
スコット・グリフィス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.