web-dev-qa-db-ja.com

pythonでバイトをビットに変換

Python3.2を使用しています。 16進ストリームを入力として受け取り、ビットレベルで解析する必要があります。だから私は使った

bytes.fromhex(input_str)

文字列を実際のバイトに変換します。これらのバイトをビットに変換するにはどうすればよいですか?

25
user904832

これを行う別の方法は、 bitstring モジュールを使用することです。

>>> from bitstring import BitArray
>>> input_str = '0xff'
>>> c = BitArray(hex=input_str)
>>> c.bin
'0b11111111'

そして、先頭の0bを削除する必要がある場合:

>>> c.bin[2:]
'11111111'

jcolladoの答えが示すように、bitstringモジュールは要件ではありませんが、入力を変換するための多くの高性能メソッドがありますビットとそれらを操作します。次の例のように、これは便利な(またはそうでない)かもしれません。

>>> c.uint
255
>>> c.invert()
>>> c.bin[2:]
'00000000'

等.

33
Alex Reynolds

整数レベルで作業すると、操作がはるかに高速になります。特に、ここで提案されている文字列への変換は本当に遅いです。

ビット7と8のみが必要な場合は、たとえば.

val = (byte >> 6) & 3

(これは、バイトを右に6ビットシフトします-ドロップします。最後の2ビットのみを保持します3は、最初の2ビットが設定された数値です...)

これらは、非常に高速な単純なCPU操作に簡単に変換できます。

20
Anony-Mousse

このようなものはどうですか?

>>> bin(int('ff', base=16))
'0b11111111'

これにより、16進数の文字列が整数に変換され、その整数は、各バイトが整数のビット値に応じて0/1に設定された文字列に変換されます。

コメントで指摘されているように、0bプレフィックスを削除する必要がある場合は、次のようにできます。

>>> bin(int('ff', base=16)).lstrip('0b')
11111111

またはこの方法:

>>> bin(int('ff', base=16))[2:]
11111111
18
jcollado

バイナリへ:

bin(byte)[2:].zfill(8)
7
Ferguzz

ここでnumpyを使用するのが最も簡単だと思います。たとえば、ファイルをバイトとして読み取り、次のように簡単にビットに展開できます。

Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)
4
Mikhail V

using python フォーマット文字列構文

_>>> mybyte = bytes.fromhex("0F") # create my byte using a hex string
>>> binary_string = "{:08b}".format(int(mybyte.hex(),16))
>>> print(binary_string)
00001111
_

2行目は、魔法が発生する場所です。すべてのバイトオブジェクトには、.hex()関数があり、16進文字列を返します。この16進数文字列を使用して、整数に変換し、int()関数に16進数の文字列であることを伝えます(16進数は16進数であるため)。次に、その整数にフォーマットを適用して、バイナリ文字列として表示します。 _{:08b}_は本当の魔法が起こる場所です。 Format Specification Mini-Language _format_spec_を使用しています。具体的には、format_spec構文のwidthおよびtype部分を使用しています。 _8_はwidthを8に設定します。これはNice 0000パディングを取得する方法であり、bは型をバイナリに設定します。

書式文字列を使用すると柔軟性が大幅に向上するため、bin()メソッドよりもこのメソッドの方が好きです。

3
ZenCodr

読み取りバイトを読み取るときにordを使用します。

_byte_binary = bin(ord(f.read(1))) # Add [2:] to remove the "0b" prefix
_

または

str.format()を使用:

_'{:08b}'.format(ord(f.read(1)))
_
2
Jacob Valenta

ここの他の答えは、ビットを ビッグエンディアン 順序で提供します('\x01''00000001'になります)

ビットのリトルエンディアン順序に興味がある場合、これは、bignumなどの一般的な表現のように、多くの場合に役立ちます-以下にスニペットを示します。

def bits_little_endian_from_bytes(s):
    return ''.join(bin(ord(x))[2:].rjust(8,'0')[::-1] for x in s)

そして、他の方向について:

def bytes_from_bits_little_endian(s):
    return ''.join(chr(int(s[i:i+8][::-1], 2)) for i in range(0, len(s), 8))
1
yairchu

ここでformat()を使用してそれを行う方法

print "bin_signedDate : ", ''.join(format(x, '08b') for x in bytevector)

8bが重要です。つまり、1つのバイトを完了するために、最大8つの先行ゼロが追加されます。これを指定しない場合、フォーマットは、変換されたバイトごとに可変ビット長を持ちます。

0
Joniale