2012-10-12 79 views
1

我有一个字节串"\x56\x20",它是两组数据,一个(12位)和b(4位)。解码字节间二进制数据

的紧缩数据预计:

A = 86 B = 2

其中:

a = int("056", 16) 
b = int("2", 16) 

我知道我可以使用binascii到字节字符串转换为十六进制字符串然后对它进行切片魔术,但这似乎很混乱。

我看着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 
>>> 

有没有更清洁的方法?

+2

如果'\ x56 \ x20'要在12位和4位部分分割,则得到1378和0,*不是* 86和2 ..除非这是小的-endian,因此应该被解释为'\ x20 \ x56'。 –

+0

好点,我只是看着十六进制编辑器中的原始字节,所以是的,它看起来应该是\ x20 \ x56。 – monkut

回答

3

您似乎将数据解释为little-endian。为了解码,具有struct进行解码,然后使用bitshifting和掩码解释他们:

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 
+1

@monkut:没关系。 :-)我很惊讶downvote,就是这样。如[Python datamodel](http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy)中所述,python整数明确支持位掩码和移位,因为这是可接受的处理方式像这些情况(也见http://wiki.python.org/moin/BitManipulation)。 –

+0

好吧,说我有这些领域的定义,像fields =(12,4)。鉴于这个定义是否有一个获得面具的程序化方法? – monkut

+1

@monkut:好的:'mask =(2 ** fields [0]) - 1'。 –

1
>>> import struct 
>>> divmod(struct.unpack('<H', '\x56\x20')[0], 2 ** 12) 
(2, 86) 
+0

这是什么黑魔法? – monkut

+0

如果你关于'divmod'函数,它只是返回元组''(a/b,a%b)'。 – defuz

+0

真的,'divmod'?太聪明了,这会在codereview中抛出。 –

2

对于非全字节数据的二进制分析像bitstring外部模块可以帮助(这肯定会当事情变得比这更复杂):

>>> from bitstring import BitArray 
>>> a = BitArray(bytes='\x20\x56') 
>>> a.unpack('uint:4, uint:12') 
[2, 86] 
+0

谢谢!看起来不错,但我想坚持这个标准库。 – monkut