Heim >Backend-Entwicklung >Python-Tutorial >Detaillierte Erläuterung der Python-Methode zur Verwendung von struct zur Verarbeitung von Binärdaten
Dieser Artikel stellt hauptsächlich relevante Informationen über die Verwendung von Strukturen zur Verarbeitung binärer Beispiele vor. Ich hoffe, dass jeder, der diesen Artikel benötigt, auf
Pythons zurückgreifen kann Verwendung von Struktur zum Verarbeiten Detaillierte Erläuterung von Binärbeispielen
Manchmal müssen Sie Python verwenden, um Binärdaten zu verarbeiten, beispielsweise beim Zugriff auf Dateien und Socket-Vorgänge. Zu diesem Zeitpunkt können Sie das Strukturmodul von Python verwenden Um es zu vervollständigen, können Sie Struktur in der Sprache C verwenden.
Die drei wichtigsten Funktionen im Strukturmodul sind pack(), unpack(), calcsize()
pack(fmt, v1, v2, ...) Packen Sie die Daten entsprechend dem angegebenen Format (fmt) in einen String (eigentlich ein Bytestream ähnlich einer C-Struktur). )
unpack(fmt, string) Analysiert die Byte-Stream-Zeichenfolge gemäß dem angegebenen Format (fmt) und gibt das analysierte Tupel zurück
calcsize (fmt) Berechnung Wie viele Bytes Speicher belegt ein bestimmtes Format (fmt)
Die unterstützten Formate in struct sind wie folgt:
Format | C-Typ | Python | Bytes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
x | Pad-Byte | kein Wert | 1 | tr>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
c | char | String der Länge 1 | 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
b | signed char | integer | 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
B | unsigned char | integer | 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
? | _Bool | bool | 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
h | short | integer | 2 | tr>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
H | unsigned short | integer | 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
iint | integer | 4 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I | unsigned int | Ganzzahl oder Long | 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
l | Long | Ganzzahl | 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
L | unsigned long | long | 4 | tr>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
q | long long | long | 8 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Qunsigned long long | long | 8 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
f | float td> | float | 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d | double | float | 8|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
s | char[] | string | 1 | tr>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
p | char[] | string | 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
P | void * | long |
|
Hinweis 1.q und Q sind nur in Es ist interessant, wenn die Maschine den 64-Bit-Betrieb unterstützt
Hinweis 2. Vor jedem Format kann eine Zahl stehen, die die Zahl angibt
Hinweis 3. Das s-Format stellt eine Zeichenfolge einer bestimmten Länge dar. und 4s stellt eine Zeichenfolge der Länge 4 dar, aber p stellt eine Pascal-Zeichenfolge dar
Hinweis 4. P wird zum Konvertieren eines Zeigers verwendet, seine Länge hängt von der Länge des Maschinenworts ab
Hinweis 5. Letzteres kann verwendet werden um den Zeigertyp darzustellen, der 4 Bytes belegt
Um Daten mit Strukturen in C auszutauschen, muss auch berücksichtigt werden, dass einige C- oder C++-Compiler die Byteausrichtung verwenden, normalerweise basierend auf 32-Bit-Systemen auf 4 Bytes, daher basiert die Struktur auf der Konvertierung der nativen Maschinenbyte-Reihenfolge. Sie können das erste Zeichen im Format verwenden, um die Ausrichtung wie folgt zu ändern:
Byte-Reihenfolge | Größe und Ausrichtung | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
native | native Ergibt 4 Bytes | |||||||||||||||
= | native | standard Drücken Sie das ursprüngliche Wort Anzahl der Abschnitte | ||||||||||||||
dcf16330690b81abbfbeac1327ae166c | Big-Endian | Standard Entsprechend der ursprünglichen Anzahl von Bytes | ||||||||||||||
! | Netzwerk (= Big-Endian)
|
Die Verwendungsmethode besteht darin, es an die erste Position von fmt zu setzen, wie „@5s6sif“
Beispiel 1:
Beispielsweise hat eine Struktur
struct Header { unsigned short id; char[4] tag; unsigned int version; unsigned int count; }
die oben genannten Strukturdaten über socket.recv erhalten, die in der Zeichenfolge s gespeichert sind. Jetzt müssen sie analysiert werden out. Sie können die Funktion unpack() verwenden.
import struct id, tag, version, count = struct.unpack("!H4s2I", s)In der obigen Formatzeichenfolge gibt ! an, dass wir die Netzwerk-Byte-Reihenfolge verwenden möchten Unsere Daten werden vom Netzwerk empfangen und in der Netzwerk-Byte-Reihenfolge angezeigt. Das folgende H steht für eine vorzeichenlose Kurz-ID, 4s steht für eine 4-Byte-lange Zeichenfolge und 2I steht für zwei vorzeichenlose Int-Daten. Bestehen Sie einfach einen Entpackvorgang, und jetzt wurden unsere Informationen in ID, Tag, Version und Anzahl gespeichert.
ss = struct.pack("!H4s2I", id, tag, version, count);Die Pack-Funktion konvertiert ID, Tag, Version, Anzahl in Struktur Header, SS gemäß dem angegebenen Format. Jetzt ist es eine Zeichenfolge (eigentlich). ein Byte-Stream ähnlich einer C-Struktur).
Zu diesem Zeitpunkt handelt es sich bei Bytes um eine Zeichenfolge, und die Zeichenfolge entspricht dem binären Speicherinhalt von a in Bytes. Führen Sie dann den umgekehrten Vorgang aus
vorhandene Binärdatenbytes (eigentlich eine Zeichenfolge) und konvertieren Sie sie zurück in den Python-Datentyp:
import struct a=12.34 #将a变为二进制 bytes=struct.pack('i',a)
Beachten Sie, dass das Entpacken ein Tupel zurückgibt
, wenn also nur eine Variable vorhanden ist:
a,=struct.unpack('i',bytes)
Dann müssen Sie dies beim Dekodieren tun
bytes=struct.pack('i',a)
Wenn es aus mehreren Daten besteht, kann es so aussehen:
a,=struct.unpack('i',bytes) 或者 (a,)=struct.unpack('i',bytes)
Die Bytes sind zu diesem Zeitpunkt binäre Daten Formular. Wir können direkt in eine Datei wie binfile.write(bytes)
schreiben und sie dann auslesen, wenn wir sie brauchen, bytes=binfile.read()
und dann übergeben struct.unpack() wird in eine Python-Variable dekodiert
a='hello' b='world!' c=2 d=45.123 bytes=struct.pack('5s6sif',a,b,c,d)
'5s6sif' Dies wird als fmt bezeichnet, eine Formatzeichenfolge , bestehend aus Zahlen und Zeichen, 5s Stellt eine Zeichenfolge mit 5 Zeichen dar, 2i, stellt 2 Ganzzahlen usw. dar. Im Folgenden sind die verfügbaren Zeichen und Typen aufgeführt. ctype gibt an, dass sie den Typen in Python eins zu eins entsprechen können.
Hinweis: Bei der Verarbeitung von Binärdateien sind Probleme aufgetreten
a,b,c,d=struct.unpack('5s6sif',bytes)
Was ist also der Unterschied zum Ergebnis von binfile=open(filepath,'r')?
Zweitens können wir für die Zeichenfolge x='abcndef' len(x) verwenden, um ihre Länge auf 7 zu bringen. Wir nennen n das Zeilenumbruchzeichen, das eigentlich „0X0A“ ist. Wenn wir im Textmodus „w“ schreiben, wird „0X0A“ auf der Windows-Plattform automatisch in zwei Zeichen „0X0D“, „0X0A“ geändert, dh die Dateilänge beträgt tatsächlich 8. Beim Lesen im Textmodus „r“ wird dieser automatisch in das ursprüngliche Zeilenumbruchzeichen konvertiert. Wenn Sie zum Schreiben in den Binärmodus „wb“ wechseln, bleibt ein Zeichen unverändert und wird beim Lesen so gelesen, wie es ist. Wenn Sie also im Textmodus schreiben und im Binärmodus lesen, müssen Sie dieses zusätzliche Byte berücksichtigen. „0X0D“ wird auch Wagenrücklaufzeichen genannt. Unter Linux wird sich das nicht ändern. Weil Linux nur „0X0A“ zur Darstellung von Zeilenumbrüchen verwendet.
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Python-Methode zur Verwendung von struct zur Verarbeitung von Binärdaten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!