/ / Strukturlänge von lang abhängig von der Bytereihenfolge? - python, python-2.7, struct

Struct Länge von Long abhängig von der Byte-Reihenfolge? - Python, Python-2.7, Struktur

Ich möchte benutzen struct.unpack() Um einen langen Wert aus einer Byte-Zeichenfolge in Python 2.7 zu erhalten, habe ich ein merkwürdiges Verhalten festgestellt und möchte wissen, ob dies ein Fehler ist oder nicht und was ich tun kann, um ihn zu umgehen.

Was passiert, ist folgendes:

import struct
>>> struct.unpack("L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 8

Dies ist das erwartete Verhalten. Es wird eine 8-Byte-Zeichenfolge benötigt, um den 8-Byte-langen Wert zu extrahieren.

Jetzt ändere ich die Bytereihenfolge in Netzwerk-Bytereihenfolge und erhalte Folgendes:

>>> struct.unpack("!L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 4

Plötzlich werden nur 4 Byte für den 8 Byte langen Wert benötigt.

Was ist damit los und was kann ich tun, um das zu umgehen?

Antworten:

1 für die Antwort № 1

Das Problem ist, dass struct verwendet die native Ihres Computers long Größe im ersten Fall und struct"s" Standard long Größe in der Sekunde.

Im ersten Beispiel geben Sie kein an Bezeichner für Byte-Reihenfolge, Größe und Ausrichtung (einer von @=<>!) so struct geht davon aus "@", der die nativen Werte Ihres Computers verwendet, nämlich die nativen Werte Ihres Computers long Größe. Um plattformübergreifend konsistent zu sein, struct definiert Standardgrößen für jeden Typ, die von den nativen Größen Ihrer Maschine abweichen können. Jeder Spezifizierer außer "@" verwendet diese Standardgrößen.

Also im Fall von long, struct"s Standard ist 4 Bytes, weshalb "!L" (oder irgendein "[=<>!]L" erwartet 4 Bytes. Ihre Maschine ist jedoch native long ist anscheinend 8 Bytes, weshalb "@L" oder "L" Erwartet 8. Wenn Sie die native Bytereihenfolge Ihres Computers verwenden möchten, aber immer noch kompatibel mit struct"s Standardgrößen würde ich empfehlen, dass Sie alle Formate mit angeben "=", anstatt Python standardmäßig verwenden zu lassen "@".


Sie können die Größenerwartung mit überprüfen struct.calcsize, d.h.

>>> struct.calcsize("@L"), struct.calcsize("=L")

(Dies kehrt zurück (4, 4) auf meinem 64-bit Windows 10 Rechner, aber (8, 4) auf meinem 64-bit Ubuntu 16.04 Rechner.)

Sie können die Typgröße Ihrer Maschine auch direkt überprüfen, indem Sie a kompilieren C Skript, um den Wert von zu überprüfen sizeof(long), beispielsweise:

#include <stdio.h>

int main()
{
printf("%li",sizeof(long));
return 0;
}

ich folgte dieser Leitfaden um das zu kompilieren C Skript auf meinem Windows 10-Computer.