如何在python中移动2-5字节长的bytes对象中的位?

2024-09-28 19:01:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从字节对象中提取数据。例如: 从b'\x93\x4c\x00'我的整数从位8隐藏到21。 我试着做bytes >> 3,但如果超过一个字节,这是不可能的。 我也尝试用struct来解决这个问题,但是byte对象必须有特定的长度。

我怎样才能把位子移到右边?


Tags: 数据对象字节bytes整数bytestructx00
3条回答

另一种适用于任意长字节序列的方法是使用bitstring库,该库允许对位字符串执行位操作,例如

>>> import bitstring
>>> bitstring.BitArray(bytes=b'\x93\x4c\x00') >> 3
BitArray('0x126980')

由于您有一个字节字符串,并且您想去掉最右边的8位(即一个字节),您可以简单地从字节字符串中删除它:

>>> b'\x93\x4c\x00'[:-1]
b'\x93L'

如果要将其转换为整数,可以使用Python的struct将其解包。正如您正确地说的,您需要固定的大小才能使用结构,因此您只需填充字节字符串即可添加所需数量的零:

>>> data = b'\x93\x4c\x00'
>>> data[:-1]
b'\x93L'
>>> data[:-1].rjust(4, b'\x00')
b'\x00\x00\x93L'
>>> struct.unpack('>L', data[:-1].rjust(4, b'\x00'))[0]
37708

当然,也可以先将其转换,然后将8位从结果整数中移开:

>>> struct.unpack('>Q', data.rjust(8, b'\x00'))[0] >> 8
37708

如果要确保实际解释的位不超过13位(位8到21),则必须应用位掩码0x1FFF当然:

>>> 37708 & 0x1FFF
4940

(如果您需要大端点,只需分别使用<L<Q。)


如果您真的是从左到右计数位(这可能不常见,但可以),那么您也可以使用填充技术:

>>> struct.unpack('>Q', data.ljust(8, b'\x00'))[0] >> 43
1206656

注意,我们正在将填充添加到另一侧,并将其移动43位(对于不需要查看的填充数据,您的3位加上5个字节)

不要使用bytes来表示整数值;如果需要位,convert to an ^{}

value = int.from_bytes(your_bytes_value, byteorder='big')
bits_21_to_8 = (value & 0x1fffff) >> 8

其中0x1fffff掩码也可以用以下公式计算:

mask = 2 ** 21 - 1

演示:

>>> your_bytes_value = b'\x93\x4c\x00'
>>> value = int.from_bytes(your_bytes_value, byteorder='big')
>>> (value & 0x1fffff) >> 8
4940

然后可以使用^{} method移回字节:

>>> ((value & 0x1fffff) >> 8).to_bytes(2, byteorder='big')
b'\x13L'

相关问题 更多 >