2011-11-02 18 views
8

Mam plik binarny, który czytam, gdzie niektóre wartości 2 bajtowe są przechowywane w kolejności odwrotnej bajtów (little endian?), Np.Jak zmienić kolejność bajtów danych binarnych

1D 00 13 00 27 00 3B 00 45 00 31 00 4F 

Oryginalny program, który utworzył te wartości, przechowuje je wewnętrznie jako krótkie. Wartości te powinny odpowiadać: 29, 19, 39, 59, 69, 49, 79. Próbuję odczytać te wartości za pomocą Pythona 2.6.5 (chociaż prawdopodobnie będzie działać na starszych systemach, np. 2.3 i 2.4) .

Próbowałem za pomocą

val1, val2, val3, val4, val5, val6, val7 = struct.unpack("1h 1h 1h 1h 1h 1h 1h", data) 

i, oczywiście, wartości wszystkich wyjdzie źle:

7427 
4864 
9984 
15104 
17664 
12544 
20224 

Po zapoznaniu się z dokumentacją struktury, myślałem, że będę w stanie użyć czegoś podobnego

val1, ... = struct.unpack("!h !h ... 

ale kiedy badania, tylko mam

struct.error: bad char in struct format 

W jaki sposób mogę rozpakować te wartości za pomocą prawidłowej kolejności bajtów? Czy utknąłem w dwóch bajtach oddzielnie, a potem ponownie zmontowałem je w kodzie Pythona?

Odpowiedz

9

Kolejność bajtów jest określona pojedynczym znakiem, na początku ciągu formatu.

values = struct.unpack('!7h', data) 
+0

Aha, to było to. Mam kilka specyfikatorów formatów w ciągu formatu, ale tylko umieściłem znak kolejności bajtów przed specyfikatorem "h" zamiast na początku całego ciągu znaków. Dzięki! – pfyon

3

Jak o

>>> a='\x1d\x00\x13\x00\x27\x00\x3b\x00\x45\x00\x31\x00\x4f\x00'

>>> struct.unpack('<%dH' % (len(a)/2), a)

(29, 19, 39, 59, 69, 49, 79)?

Zgodnie z dokumentacją struct wygląda na to, że trzeba użyć <, aby określić little-endian.

0

Rozwiązałem podobny problem z odwrotną kolejnością bajtów za pomocą a.byteswap(True), ale nie jestem pewien, czy jest to najbardziej efektywna metoda.