2011-10-31 13 views
5
में struct का उपयोग कर एक पूर्णांक के रूप में 6 बाइट्स को अनपैक करने के

मैं निम्नलिखित 8 बाइट्स है:कैसे अजगर

b'\x05\x00\x00\x00\x00\x00\x05\x00' 

मैं struct.unpack का उपयोग कर दो पूर्णांकों पाने के लिए कोशिश कर रहा हूँ:, पहले 2 बाइट्स के लिए एक और पिछले 6. पहले दो प्राप्त करने के लिए एक का उपयोग करना आसान है:

struct.unpack("<H6B") 

लेकिन, वह रिटर्न

(5, 0, 0, 0, 0, 5, 0) 

मैं इसे करना चाहते हैं निम्नलिखित को वापस करें:

(5, 5) 

मैं पिछले 6 बाइट्स का पूर्णांक मान कैसे प्राप्त करूं? मैं व्यक्तिगत रूप से प्रत्येक बाइट नहीं चाहता।

उत्तर

10

struct गैर-शक्ति के दो आकार वाले पूर्णांक का समर्थन नहीं करता है। यह आम है। सी आपके प्लेटफ़ॉर्म पर ऐसे पूर्णांक का समर्थन नहीं करता है (ठीक है, बिटफील्ड, लेकिन आप उनमें से कोई सरणी नहीं बना सकते हैं)।

def unpack48(x): 
    x1, x2, x3 = struct.unpack('<HHI', x) 
    return x1, x2 | (x3 << 16) 
+0

यह चाल है। धन्यवाद! –

3

मानक struct मॉड्यूल सभी संभावित आकारों का समर्थन नहीं करता तो आप या तो (Dietrich के जवाब देखें) कुछ बिट्स एक साथ अपने आप को शामिल होने के लिए है, या आप इस तरह के bitstring के रूप में बाहरी मॉड्यूल का उपयोग कर सकते हैं।

>>> from bitstring import BitArray 
>>> b = BitArray(bytes=b'\x05\x00\x00\x00\x00\x00\x05\x00') 
>>> b.unpack('<H6B') 
[5, 0, 0, 0, 0, 5, 0] 

जो मानक struct.unpack के समान है। लेकिन अब हम बजाय एक 6 बाइट (48 बिट) के रूप में दूसरा आइटम अहस्ताक्षरित पूर्णांक खोल सकते हैं थोड़ा-endian:

>>> b.unpack('<H, uintle:48') 
[5, 21474836480]     

जो आप और Dietrich के जवाब के रूप में एक ही परिणाम देता है यह भी पता चलता है कि आप कुछ गलत मिल गया है कि अपने सवाल में रास्ता दौर! क्या आप इस मामले में की जरूरत है:

>>> b.unpack('uintle:48, <H') 
[5, 5] 

ध्यान दें कि आप भी अगर आप अधिक सुसंगत अंकन चाहता था uintle:16 रूप <H लिख सकते हैं।