我想使用Python 3将文件的确切位序从文件中提取到字符串中。关于这个主题的几个问题很接近,但是并没有完全回答它。到目前为止,我有这个:
>>> data = open('file.bin', 'rb').read()
>>> data
'\xa1\xa7\xda4\x86G\xa0!e\xab7M\xce\xd4\xf9\x0e\x99\xce\xe94Y3\x1d\xb7\xa3d\xf9\x92\xd9\xa8\xca\x05\x0f$\xb3\xcd*\xbfT\xbb\x8d\x801\xfanX\x1e\xb4^\xa7l\xe3=\xaf\x89\x86\xaf\x0e8\xeeL\xcd|*5\xf16\xe4\xf6a\xf5\xc4\xf5\xb0\xfc;\xf3\xb5\xb3/\x9a5\xee+\xc5^\xf5\xfe\xaf]\xf7.X\x81\xf3\x14\xe9\x9fK\xf6d\xefK\x8e\xff\x00\x9a>\xe7\xea\xc8\x1b\xc1\x8c\xff\x00D>\xb8\xff\x00\x9c9...'
>>> bin(data[:][0])
'0b11111111'
好的,我可以得到一个基数为2的数字,但我不明白为什么数据[:] [x],而我仍然有前导0b。似乎我必须遍历整个字符串并进行一些转换和解析以获得正确的输出。有没有更简单的方法来获取01的序列而不需要循环,解析和连接字符串?
提前致谢!
答案 0 :(得分:6)
我首先预先计算所有值0..255
的字符串表示形式bytetable = [("00000000"+bin(x)[2:])[-8:] for x in range(256)]
或者,如果您更喜欢LSB到MSB顺序的位
bytetable = [("00000000"+bin(x)[2:])[-1:-9:-1] for x in range(256)]
然后可以用
获得二进制文件binrep = "".join(bytetable[x] for x in open("file", "rb").read())
答案 1 :(得分:2)
目前尚不清楚比特序列是什么意思。我认为从字节0开始用位0最自然,但它实际上取决于你想要的东西。
所以这里有一些代码来访问从字节0中的位0开始的位序列:
def bits_from_char(c):
i = ord(c)
for dummy in range(8):
yield i & 1
i >>= 1
def bits_from_data(data):
for c in data:
for bit in bits_from_char(c):
yield bit
for bit in bits_from_data(data):
# process bit
(另请注意:您的代码中不需要data[:][0]
。只需data[0]
即可,但不先复制整个字符串。)
答案 2 :(得分:2)
如果您可以使用外部模块,则使用bitstring:
>>> import bitstring
>>> bitstring.BitArray(filename='file.bin').bin[2:]
'110000101010000111000010101001111100...'
就是这样。它只需要整个文件的二进制字符串表示,并切断一个初始'0b'。
答案 3 :(得分:1)
将原始二进制数据(例如b'\xa1\xa7\xda4\x86'
)转换为位串,该位串在Python 3中将数据表示为二进制系统(base-2)中的数字:
>>> data = open('file.bin', 'rb').read()
>>> bin(int.from_bytes(data, 'big'))[2:]
'1010000110100111110110100011010010000110...'