2011-10-31 5 views
5

Mam następujący 8 bajtów:Jak rozpakować 6 bajtów jako jedna liczba całkowita używając struct w Pythonie

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

Próbuję dostać dwie liczby całkowite użyciu struct.unpack: jedna dla pierwszych 2 bajtów, a jeden dla ostatniego 6. pierwsze dwa pierwsze jest łatwe przy użyciu:

struct.unpack("<H6B") 

jednak, że wraca

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

chcę go Zwróć następujące:

(5, 5) 

Jak uzyskać wartość całkowitą z ostatnich 6 bajtów? Nie chcę każdego bajtu osobno.

Odpowiedz

10

struct nie obsługuje liczb całkowitych o rozmiarze nie-mocy-dwóch. Jest to częste. C nie obsługuje takich liczb całkowitych na twojej platformie (dobrze, bitfields, ale nie możesz ich utworzyć).

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

To załatwiło sprawę. Dzięki! –

3

Standardowy moduł struct nie obsługuje wszystkich możliwych rozmiarach, więc albo trzeba dołączyć jakieś bity razem samemu (patrz odpowiedź Dietrich), można też korzystać z modułów zewnętrznych, takich jak 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] 

, który jest taki sam jak standardowy struct.unpack. Ale teraz możemy zamiast rozpakować drugą pozycję jako 6 bajtów (48 bitów) little-endian unsigned integer:

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

co daje taki sam wynik jak odpowiedź Dietrich, a także pokazuje, że masz coś źle sposób w twoim pytaniu! Co trzeba w tym przypadku jest:

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

Zauważ, że można też pisać <H jak uintle:16 jeśli chcieliśmy bardziej spójnej notacji.

Powiązane problemy