Python 八位组间二进制数据的解码

Python 八位组间二进制数据的解码,python,binary,Python,Binary,我有一个bytestring“\x56\x20”,它是两组数据,a(12位)和b(4位) 未打包的数据预计为: a=86 b=2 其中: a = int("056", 16) b = int("2", 16) 我知道我可以使用binascii将bytestring转换为十六进制字符串,然后在其上使用slice magic,但这看起来很混乱 我查看了struct,但找不出一种方法来拆分12位/4位 >>> import binascii >>> two_oct

我有一个bytestring
“\x56\x20”
,它是两组数据,a(12位)和b(4位)

未打包的数据预计为:

a=86 b=2

其中:

a = int("056", 16)
b = int("2", 16)
我知道我可以使用
binascii
将bytestring转换为十六进制字符串,然后在其上使用slice magic,但这看起来很混乱

我查看了
struct
,但找不出一种方法来拆分12位/4位

>>> import binascii
>>> two_octets = "\x56\x20"
>>> hex_str = binascii.hexlify(two_octets)
>>> temp_a, temp_b = hex_str[:2], hex_str[2:]
>>> a_part, b_part = reversed([c for c in temp_b])
>>> int(a_part + temp_a, 16)
86
>>> int(b_part, 16)
2
>>>

有更干净的方法吗?

您似乎将数据解释为小端。要解码,请使用
struct
进行解码,然后使用位移位和掩码对其进行解释:

import struct
two_octets = '\x56\x20'
values = struct.unpack('<H', two_octets)[0]
a = values & 0xFFF  # Select right-most 12 bits
b = values >> 12    # Select left-most 4 bits
导入结构
两个八位字节='\x56\x20'

values=struct.unpack(“您似乎将数据解释为小端。要进行解码,请使用
struct
进行解码,然后使用位移位和掩码进行解释:

import struct
two_octets = '\x56\x20'
values = struct.unpack('<H', two_octets)[0]
a = values & 0xFFF  # Select right-most 12 bits
b = values >> 12    # Select left-most 4 bits
导入结构
两个八位字节='\x56\x20'
values=struct.unpack('
>>import struct
>>>divmod(结构解包('
>>>导入结构

>>>divmod(struct.unpack(“对于非整字节数据的二进制分析,像外部模块这样的模块可能会有所帮助(当事情变得比这更复杂时,它肯定会有帮助):


对于非整字节数据的二进制分析,像这样的外部模块可能会有所帮助(当事情变得比这更复杂时,它肯定会有帮助):



如果将
\x56\x20
拆分为12位和4位部分,则得到1378和0,而不是86和2在一个4位的部分中,你得到的是1378和0,而不是86和2。除非这是小尾数,因此应该解释为
\x20\x56
真的。好的一点,我只是在十六进制编辑器中查看原始字节,所以是的,它看起来应该是\x20\x56。如果你的about
divmod
函数,它只返回tuple
(a/b,a%b)
。真的吗,
divmod
?太聪明了一半,这会在代码审查中被抛弃。@MartijnPieters,请你解释一下你的意思好吗?使用
divmod
从两个字节中提取两个独立的值,可能是一种半聪明的方法,但与处理此类字节的正常方式相去甚远。这会使你的代码变得不完整-可维护的,我希望一个半经验丰富的开发人员能够理解位移位和掩码,但是当遇到这种技巧时,需要比严格必要的多得多的挠头。因此,如果我在代码审查中遇到这种情况,我会拒绝它,或者用位移位和掩码操作代替它。@MartijnPieters,老实说,我不知道这可能会导致什么问题。另外,在我的例子中,移位只给出一次,在-中给出两次,这可能会导致潜在的问题。如果我遇到更难处理移位的情况,也会使用位移位。但在这方面,我认为没有理由不使用简单除法。如果您的about
divmod
函数只需返回元组
(a/b,a%b)
。真的吗,
divmod
?太聪明了一半,这会在代码审查中被抛弃。@MartijnPieters,请你解释一下你的意思好吗?使用
divmod
从两个字节中提取两个独立的值,可能是一种半聪明的方法,但与处理此类字节的正常方式相去甚远。这会使你的代码变得不完整-可维护的,我希望一个半经验丰富的开发人员能够理解位移位和掩码,但是当遇到这种技巧时,需要比严格必要的多得多的挠头。因此,如果我在代码审查中遇到这种情况,我会拒绝它,或者用位移位和掩码操作代替它。@MartijnPieters,老实说,我不知道这可能会导致什么问题。此外,在我的情况下,轮班是一次,在你的-两次,这可能会导致潜在的问题。如果我有一个更困难的情况下与轮班工作,也会使用位移。但在这方面,我认为没有理由不使用简单的除法。谢谢!看起来不错,但我想坚持这个原则标准库。谢谢!看起来不错,但我想坚持使用标准库。@monkut:很好。:-)我对否决票感到惊讶,仅此而已。如中所述,python整数明确支持位屏蔽和移位,因为这是处理此类情况的公认方法(另请参阅)。好的,假设我对这些字段有一个定义,类似于字段=(12,4)。有了这个定义,有没有一种编程方式来获取掩码?@monkut:Sure:
mask=(2**fields[0])-1
@monkut:It's罚款。:-)我对向下投票感到惊讶,仅此而已。如中所述,python整数明确支持位屏蔽和移位,因为这是处理此类情况的公认方式(另请参见)。好吧,假设我对这些字段有一个定义,类似于fields=(12,4).根据该定义,是否有一种编程方式来获取掩码?@monkut:Sure:
mask=(2**fields[0])-1
>>> from bitstring import BitArray
>>> a = BitArray(bytes='\x20\x56')
>>> a.unpack('uint:4, uint:12')
[2, 86]