In PHP ist die Funktion pack () ein sehr nützliches Instrument zum Konvertieren von Daten in Binärzeichenfolgen, die für die Verwendung in Netzwerkübertragung oder Dateioperationen zweckmäßig sind. Viele Entwickler haben jedoch festgestellt, dass die Verwendung derselben Pack () -Funktion auf verschiedenen Plattformen (wie Windows, Linux und MacOS) manchmal die binären Datenpackungen nicht genau gleich sind. Warum ist das? Dieser Artikel wird aus den Perspektiven der zugrunde liegenden Mechanismen, Plattformunterschiede und Lösungen ausführlich analysiert.
Die Funktion Pack () verpackt ein oder mehrere Daten nach dem angegebenen Format in binäre Zeichenfolgen. Gemeinsame Formate sind:
C : Signierte Zeichen (1 Byte)
C : Unsignierte Zeichen (1 Byte)
S : Signierte kurze Ganzzahl (2 Bytes)
S : Unsigned Short Ganzzahl (2 Bytes)
L : Unterzeichnete lange Ganzzahl (4 Bytes)
L : nicht signierte lange Ganzzahl (4 Bytes)
F : Einfach Präzisionsschwimmpunktzahl (4 Bytes)
D : doppelte Präzisionsschwimmpunktzahl (8 Bytes)
Zum Beispiel:
$data = pack("Nn", 0x12345678, 0x1234);
echo bin2hex($data);
Dieser Code verpackt Ganzzahlen in Network Endiangess (Big-Endian), und die Ergebnisse sollten auf jeder Plattform konsistent sein.
Der Unterschied liegt hauptsächlich daran, dass im Format von Pack () Symbole vorhanden sind und standardmäßig von der Plattform -Byte -Reihenfolge und der Datentypgröße abhängen, z. B.:
S und S : entspricht "kurzen Ganzzahlen", deren Bytereihenfolge und -größe von der Plattform abhängt (normalerweise 2 Bytes, aber auf sehr wenigen Plattformen unterschiedlich).
L und L : entsprechen "Long Integer", und ihre Größe und Endianess hängen auch von der Plattform ab, normalerweise 4 Bytes, aber einige Plattformen sind möglicherweise 8 Bytes.
Darüber hinaus gibt es zwei Mainstreams von Endian Order:
Big-Endian : Hohe Bytes werden bei niedrigen Adressen gespeichert
Little-Endian : Niedrige Bytes werden in niedriger Adresse gespeichert
Die CPUs auf verschiedenen Plattformen verwenden unterschiedliche Endianess:
Plattform/Architektur | Byte -Bestellung |
---|---|
Windows (x86/x64) | Little-Endian |
Linux (x86/x64) | Little-Endian |
macos (Intel) | Little-Endian |
macos (Arm) | Little-Endian |
Einige eingebettete Plattformen | Wahrscheinlich Big-Endian |
S und L in pack () hängen von der nativen Endianges der Maschine ab, sodass die Ausgabe desselben Code unter verschiedenen Architekturen oder Betriebssystemen unterschiedlich ist.
<?php
// Packen Sie eine kurze Ganzzahl ein 0x1234
$data = pack("s", 0x1234);
echo bin2hex($data);
?>
Auf kleinen Endplattformen (z. B. die meisten X86 Windows/Linux) kann die Ausgabe sein: 3412
Das Ausgabeergebnis auf der Big-Endian-Plattform kann: 1234 sein
Dies liegt daran, dass S von der Plattformendianthess abhängt.
Um sicherzustellen, dass die Ausgabedaten von Pack () über Plattformen hinweg konsistent sind, wird empfohlen:
Verwenden Sie Formatters zur Angabe der Byte -Reihenfolge
PHP bietet Netzwerk -Byte -Bestellformat:
N : Unsigned Short Integer (16 Bit), Netzwerk Endiangess (Big Endian)
N : Unsigned Long Ganzzahl (32 Bit), Netzwerk Endiangess (Big Endian)
Vermeiden Sie es, S und L zu verwenden, die von der nativen Endianess abhängen, und verwenden Sie stattdessen N und N.
Passen Sie die Byte -Bestell -Konvertierung an
Wenn Sie das native Endian -Format verwenden müssen, können Sie zuerst Pack () verwenden und dann die Endiangess mithilfe von Funktionen wie pack () und strrev () manuell konvertieren.
Bestimmte Datengröße
Wenn die Datengröße ungewiss ist, ist es am besten, S und L nicht zu verwenden, sondern S und L (nicht signiert) zu verwenden und sie mit Netzwerk -Endiangness zu kombinieren.
<?php
// Verwenden Sie die Netzwerkendianness, um eine plattformübergreifende Konsistenz sicherzustellen
$short = 0x1234;
$long = 0x12345678;
// packEine nicht signierte kurze Ganzzahl und eine nicht signierte lange ganze Zahl,Alle Netzwerk -Byte -Reihenfolge(Big Endian)
$data = pack("nN", $short, $long);
// Drucken Sie die Hexadezimalstrich aus
echo bin2hex($data);
?>
Unabhängig davon, ob Sie unter Windows, Linux oder MacOS ausgeführt werden, ist die Ausgabe:
123412345678
Einige Formatters von pack () hängen von der Plattformendiangess und der Datengröße ab, was zu einer inkonsistenten plattformübergreifenden Ausgabe führt.
Häufig verwendete Formate S , S , L und L können in verschiedenen Systemen unterschiedlich funktionieren.
Die Verwendung von Netzwerk-Byte-Bestellformaten N und N kann eine plattformübergreifende Konsistenz von Daten sicherstellen.
Das Verständnis der Plattform-Byte-Reihenfolge und der Datentypgröße ist der Schlüssel, um plattformübergreifende Binärdatenfehler zu vermeiden.
Wenn Sie diese Details verstehen, können Sie die Struktur binärer Daten besser kontrollieren und Kompatibilitätsprobleme in verschiedenen Programmenumgebungen vermeiden.