Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中,如何在2-5字节长的字节对象中移位位?_Python_Python 3.x_Binary Data_Bit Shift - Fatal编程技术网

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

在python中,如何在2-5字节长的字节对象中移位位?,python,python-3.x,binary-data,bit-shift,Python,Python 3.x,Binary Data,Bit Shift,我试图从字节对象中提取数据。例如: 从b'\x93\x4c\x00'my integer从第8位到第21位隐藏。 我试图做字节>>3,但如果超过一个字节,这是不可能的。 我也尝试用struct解决这个问题,但是byte对象必须有一个特定的长度 如何将位向右移位?您可以将字节转换为整数,然后乘以或除以二的幂来完成移位因为您有一个字节字符串,并且您想要去掉最右边的八位(即一个字节),您可以简单地从字节字符串中删除它: >>> b'\x93\x4c\x00'[:-1] b'\x93L

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


如何将位向右移位?

您可以将字节转换为整数,然后乘以或除以二的幂来完成移位

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

>>> b'\x93\x4c\x00'[:-1]
b'\x93L'
如果要将其转换为整数,可以使用Python对其进行解压缩。正如您所说的,使用structs需要一个固定的大小,因此只需填充bytes字符串即可添加所需数量的零:

>>> 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),则必须应用位掩码
0x1ff
,当然:

>>> 37708 & 0x1FFF
4940

(如果您需要大端,只需使用
就可以了,不要使用
字节来表示整数值;如果您需要位,则:

其中,
0x1FFFF
掩码也可以通过以下公式计算:

mask = 2 ** 21 - 1
演示:

然后,您可以使用以下命令移回字节:


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

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

在Perl中,您将使用
my$i=(unpack('N',substr(“\x00\x00”。$s,-4))>>8)&0x1ff;
。请注意,位从右到左从0开始计数;位8是
\x4c
字节的最后一位,位21到16是第一个字节的最后一个最右边的5位。移位3表示从左到右计数位;也许您正在寻找与约定不同的一组位?注意that
int.from_bytes()
不需要填充,也可以采用大于8的字节大小。对于那些通过谷歌找到解决方案的人:请注意,此解决方案仅适用于使用Python 3的情况。Python 2中的
int
类没有
from\u bytes
方法。@larsks:是的,问题是专门用标签标记的。:-)要获得8-21位,您可以删除前8位,然后从剩余部分中获取13位:。要从
x
中获取
n
位,从
offset
开始:
get_bits=lambda x,n,offset=0:(x>>offset)&-(1
mask = 2 ** 21 - 1
>>> your_bytes_value = b'\x93\x4c\x00'
>>> value = int.from_bytes(your_bytes_value, byteorder='big')
>>> (value & 0x1fffff) >> 8
4940
>>> ((value & 0x1fffff) >> 8).to_bytes(2, byteorder='big')
b'\x13L'
>>> import bitstring
>>> bitstring.BitArray(bytes=b'\x93\x4c\x00') >> 3
BitArray('0x126980')