Pythonとscapyを使用していくつかのデータを解析したいので、単一ビットを分析する必要があります。しかし、現時点では、次のようないくつかのペイロードを持つUDPパケットの例があります。
bytes = b'\x18\x00\x03\x61\xFF\xFF\x00\x05\x42\xFF\xFF\xFF\xFF'
以下のように単一のビットにアクセスできるようにバイトを変換するエレガントな方法はありますか?
bytes_as_bits = convert(bytes)
bit_at_index_42 = bytes_as_bits[42]
それはうまくいきます:
def access_bit(data, num):
base = int(num // 8)
shift = int(num % 8)
return (data[base] & (1<<shift)) >> shift
バイナリ配列を作成したい場合は、次のように使用できます。
[access_bit(data,i) for i in range(len(data)*8)]
ビット文字列が必要な場合、または関数を作成しないようにする場合は、format()とord()を使用します。簡単な例を使って説明します
bytes = '\xf0\x0f'
bytes_as_bits = ''.join(format(ord(byte), '08b') for byte in bytes)
これは「1111000000001111」を出力するはずです
最初にLSBが必要な場合は、format()の出力を反転させるだけでよいので、次のようにします。
bytes = '\xf0\x0f'
bytes_as_bits = ''.join(format(ord(byte), '08b')[::-1] for byte in bytes)
これは「0000111111110000」を出力するはずです
今、あなたはb'\xf0\x0f'
の代わりに '\xf0\x0f'
。 python2の場合、コードは同じように機能しますが、python3の場合は、ord()を削除する必要があります。
bytes = b'\xf0\x0f'
bytes_as_bits = ''.join(format(byte, '08b') for byte in bytes)
そして、ひもを弾くことは同じ問題です。
>>> n=17
>>> [(n & (1<<x))>>x for x in [7,6,5,4,3,2,1,0]]
[0, 0, 0, 1, 0, 0, 0, 1]
うーん、これはPythonの組み込みビット型ではありませんが、次のようなことができます
>>> bin(int.from_bytes(b"hello world", byteorder="big")).strip('0b')
'1101000011001010110110001101100011011110010000001110111011011110111001001101100011001'