与比特流的工作

3

我有一个base64编码的比特流需要处理。使用base64.b64decode解码后,我得到了一个包含解码代码的bytes对象(使用Py3k)。现在的问题是,我想对这个bytes对象进行位运算,例如移位、位与等,但是由于它是一个字节序列,所以这是不可能的。

有没有办法在解码后的代码上使用二进制操作呢?


1
你可以把它转换为一个单一的(长)整数,然后对其进行操作。 - Knio
@Knio:请将其发布为答案,而不是评论。 - S.Lott
3个回答

4

尝试使用

list(bytestring)

举例:

>>> bstring=b"Hello World"
>>> list( bstring)
[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
>>> 

如果您想要一个巨大的位域而不是所有这些八位组。
>>> from functools import reduce
>>> reduce(lambda x,y:(x<<8)+y,list(b"Hello World"))
87521618088882533792115812
>>> bin(_)
'0b100100001100101011011000110110001101111001000000101011101101111011100100110110001100100'
>>> 

您没有说明如何计算位数,也许它们应该被反转。

>>> reduce(lambda x,y:(x<<8)+y,list(b"Hello World"[::-1]))
121404708493354166158910792
>>> bits=bin(_)[2:]

并且将字符串填充到偶数个字节
>>> bits=bits.zfill(((len(bits)-1)//8+1)*8)
>>> bits
'0110010001101100011100100110111101010111001000000110111101101100011011000110010101001000'

将前6位转换为整数

>>> int(bits[:6],2)
25

然后是接下来的4个比特

>>> int(bits[6:10],2)
1

问题在于我需要在每个字节之间进行操作。例如,对于字节1的6位,然后是剩余的2位和字节2的前2位等等。 - poke
好的,我添加了如何创建一个大长的位域 :) - John La Rooy
我之前也有类似的经历,但我不太喜欢必须在字符串之间进行切换,因为这样做会消耗很多资源。我希望在处理纯二进制数据时有更本地化的方法。 - poke

2

如果您需要使您的bytes对象可变,那么可以从中构建一个bytearray

mutable = bytearray(b"immutable")

这将允许您通过普通赋值修改单个字节。
mutable[0] = mutable[1] = 32

如果需要进行位运算,我建议尝试使用bitstring(请原谅我推荐自己的模块)。它适用于Python 3,并允许您进行位切片、移位、逻辑运算等等。
>>> s = bitstring.BitArray(bytes=b'your_bytes_object')
>>> s.hex
'0x796f75725f62797465735f6f626a656374'
>>> ten_bits = s[5:15]
>>> print(ten_bits, ten_bits.int)
0b0010110111 183
>>> print(ten_bits << 2)
0b1011011100
>>> print(s[0:6] & '0b110100')
0b010100

0
如果您正在使用Python 2.x,可以尝试使用Construct。它可以非常优雅地解析数据,包括位数据
最近它没有太多活跃的开发,所以我不确定让它适用于Python 3.x需要什么工作。但对于2.x来说,它非常棒。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接