2012-10-12 81 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