|
Diese Seite zeigt Informationen zur Umwandlung von Daten zwischen verschiedenen Typen. Jede Programmiersprache bietet dazu Funktionen, soweit es die Umwandlung 'innerhalb' von Programmen betrifft. |
Die Funktionen dieser Seite zeigen jedoch Möglichkeiten zur Umwandlung von
Daten 'außerhalb' von Programmen, d.h. beim Lesen und Schreiben externer Daten,
z.B. von Dateien. Die klassische Heimat dieser Funktionen ist Perl, mittlerweile verbreiten sie sich auch in andere Programmiersprachen. |
Perl
|
Scripts für CGI und Systemverwaltung |
| pack | Codierung von Variablen zu Binär-Strings |
| unpack | Decodierung von Binär-Strings zu Variablen |
| templates | Typen-Symbole für die Funktionen pack und unpack |
| mydump | Funktion zum Experimentieren mit pack und unpack |
| Verwandte Themen | Formatierung mit Funktion sprintf |
| Links |
Ausgewählte
|
Funktion pack |
|
|
Diese Funktion dient zur Codierung - Umwandlung interner
Daten (aus Variablen) in beliebige externe Datentypen - z.B. für die Ausgabe
an Dateien. Template ist ein String aus Typen-Symbolen (s.u.) und Zahlen. Damit werden die Regeln für die Ausgabe der Daten festgelegt. Liste ist eine Liste von Variablen, welche in der angegebenen Reihenfolge so codiert werden, wie Template angibt. |
Syntax:
pack (Template,Liste)
Beachten sie beim
→ Lesen und
→ Schreiben von Binär-Dateien auf Win-System die Festlegung
von binmode - ansonsten werden unabsichtlich alle
Bytes 0A in 0D0A umgewandelt.
|
String-Beispiele:$t1 erzeugt "ABCD": Jede der Zahlen 65..68 wird mit Symbol c zu einem → ASCII-String codiert.$t2 verwendet den Operator .. zur Erzeugung aller Zahlen von 97 bis 103. Das Symbol * bedeutet 'so oft wiederholen wie Elemente in der Liste vorhanden sind'. $t3 ergibt wieder "ABCD": Symbol c (mal 4) codiert die Hex-Zahlen 0x41..0x44 zu einem → ASCII-String. $t4 ergibt "abc\0": Symbol a codiert (nur) eine Variable und füllt bis zur angegebenen Länge (hier 4) mit Null-Bytes. $t5 erzeugt den String "ab\0xy". a2 codiert 2 Zeichen, x fügt ein Null-Byte dazu. |
$t1 = pack('cccc',65,66,67,68);
# $t1 = 'ABCD';
$t2 = pack('c*',97..103);
# $t2='abcdefg';
$t3 = pack('c4',0x41,0x42,0x43,0x44);
# $t3 = 'ABCD'
$t4 = pack('a4','abc','x');
# $t4 = "abc\0";
$t5 = pack('a2xa2','abc','xyz');
# $t5 = "ab\0xy";
|
Beispiele mit Ganzen Zahlen:$t6 erzeugt die Bytes 01 00$t7 erzeugt die Bytes 00 01 $t8 erzeugt die Bytes FF FF $t9 erzeugt die Bytes 40 30 20 10 $t10 erzeugt wie $t8 die Bytes FF FF Die erzeugten Strings kann man z.B. in Binär-Dateien speichern. |
$t6 = pack('S',1);
$t7 = pack('S',256); $t8 = pack('S',65535); $t9 = pack('L',0x10203040); $t10 = pack('s',-1); |
Gleitkomma-Beispiele:$ta erzeugt die Bytes AB AA AA 3FDecodierung dieser Bytes zu $ra ergibt die Zahl 1.333333307 und zeigt damit die Grenzen der Single-Genauigkeit. $tb erzeugt die Bytes 55 55 55 55 55 55 F5 3F Decodierung zu $rb ergibt die Zahl 1.33333333333333 Die erzeugten Strings $ta,$tb können z.B. in Binär-Dateien gespeichert werden. ♦ Details zum Gleitkomma-Standard IEEE-754. |
$ta = pack('f',4/3);
$ra = unpack('f',$ta); $tb = pack('d',4/3); $rb = unpack('d',$tb); |
|
Vorsicht !
Einige Optionen der Funktionen pack
und unpack sind von der Umgebung (Betriebssystem)
abhängig. Je nach System kann z.B. die Länge der Variablen oder die
Reihenfolge der Bytes varieren.
|
Testen sie daher nach Möglichkeit ihre Programme bzw. die codierten / decodierten Daten auf allen erreichbaren Systemen ! |
Funktion unpack |
|
|
Diese Funktion dient zur Decodierung - Umwandlung beliebiger
externer Daten (z.B. aus Binär-Dateien) in interne Daten (Variablen). Ältere Programme oder solche, die unbedingt Platz sparen müssen, speichern ihre Daten als Binär-Strings. |
Mit unpack können sie die Daten solcher files
decodieren. (Wenn sie selbst Daten speichern, dann verwenden sie dazu am besten das
→
XML-Format. ) Die Syntax entspricht jener von Funktion pack (s.o.) |
|
Beispiel:
Die Zerlegung eines Strings (Zeichenkette, Text) in ein Array, dessen Elemente die
→
Zeichencodes der einzelnen Zeichen enthalten.
|
$s = 'Test';
@ac = unpack('c*',$s); # @ac = (84,101,115,116);
|
|
Beispiel:
Zunächst wird in der for-Schleife ein
Binärstring $t (Länge 256 byte) erzeugt, welcher
sämtliche möglichen Werte enthält (0x00..0xFF).Anm.: ein Binärstring ist ebenso wie ein 'gewöhnlicher' String eine Folge von Bytes, diese können jedoch jeden beliebigen Wert annehmen, nicht nur druckbare Zeichen. Der Binärstring wird mit Funktion unpack in einen (lesbaren) String $x von Hex-Zeichen umgewandelt.. Man könnte diesen String $x bereits ausgeben, das wäre jedoch unübersichtlich. Deshalb wird der String $x mit Funktion dump_format in eine halbwegs lesbare Form gebracht: Nach jedem Byte folgt ein Leerzeichen, nach je 16 Byte eine neue Zeile. Die Ausgabe sieht so aus:
00 01 02 03 ... 0D 0E 0F
... F0 F1 F2 F3 ... FD FE FF |
# Binärstring erzeugen
$t="";for($i=0;$i<256;$i++) {$t.=chr($i);} # Binärstring decodieren und anzeigen
$x=uc(unpack('H*',$t));print dump_format($x)."\n"; sub dump_format {
my $s = shift;
}
my $i=0; my $j=0; my $t=''; for($i=0;$i<length($s);$i+=2) {
$t.=substr($s,$i,2);
}if($j<15) {$t.=' '; $j++;} else {$t.="\n"; $j=0;} return ($t); |
|
Beispiel:
Hier wird das Modell einer Binärdatei gelesen und decodiert.
Sie enthält Strukturen fixer Länge (16 Byte für leichtes Debuggen),
die jeweils aus einer ganzen Zahl (2 Byte), aus einem ASCII-String (10 Zeichen)
und aus einer Gleitkomma-Zahl (4 Byte) bestehen.▪ Beachten sie beim Lesen und Schreiben von Binär-Dateien auf Win-System die Festlegung von binmode - ansonsten werden unabsichtlich alle Bytes 0A in 0D0A umgewandelt. ▪ Funktion read liest je eine Struktur (16 Byte) von der Datei in Variable $rec . ▪ Mit Funktion substr wird der jeweilige Teil-String isoliert. ▪ Mit Funktion unpack werden die Daten je nach Type decodiert. ▪ Strings werden hier mit einem Regulären Ausdruck von überschüssigen Leerzeichen (trailing spaces) befreit. ▪ Die decodierten Daten können sofort ausgewertet oder (hier) für eine nachfolgende getrennte Auswertung (hier: in den Arrays @d_nr, @d_name, @d_z ) gespeichert werden. ▪ Zuletzt werden die entnommenen und decodierten Daten in einer Schleife angezeigt. Sie steht stellvertretend für die nachfolgende Auswertung der Daten. |
$ok = open(BINREAD,$io_path);
if(!$ok) {die 'Fehler';} binmode BINREAD; ### Datei lesen
my (@d_nr,@d_name,@d_z);$nrec=-1; $bread=1; while($bytes_read) {
$bread=read(BINREAD,$rec,16);
}if($bread==16) {
$nrec++;
}# i*2
$dat=substr($rec,0,2);$d_nr[$nrec]=unpack('S',$dat); # string*10
$dat=substr($rec,2,10);$dat=~s/\s*$//; $d_name[$nrec]=$dat; # f*4
$dat=substr($rec,12,4);$d_z[$nrec]=unpack('f',$dat); elsif($bread) {print "Fehler\n";} close BINREAD; ### Auswertung
$i=@dat_nr;print "Auswertung ($i records)\n"; for($i=0;$i<@dat_nr;$i++) {
print "($i)";
}
print ' i*2=' .$d_nr[$i]; print ' s*10='.$d_name[$i]; print ' f*4='.$d_z[$i]."\n"; |
Typen-Symbole (Templates) für pack & unpack (Auswahl) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Eine nachgestellte Zahl kann je nach Symbol unterschiedliche Bedeutung haben: ▪ Für Strings bezeichnet die Zahl die String-Länge. Jedes String-Symbol codiert / decodiert nur eine einzige Variable der Liste zu einem String der angegebenen Länge. |
▪
Für alle anderen Symbole bezeichnet die Zahl die Anzahl der Wiederholungen.
Ein Template-String "d2S4" bewirkt die Umwandlung
von 2 Double-Gleitkomma-Zahlen zu je 8 Byte und 4 Ganzen Zahlen zu je 2 Byte, d.h.
codiert / decodiert einen Binär-String von insgesamt 24 Byte Länge. Ein * als Multiplikator bedeutet: So oft wiederholen, als noch Elemente in der Liste sind. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
Perl: perlfunc (standardfunktionen) -
pack
& unpack PHP: Offizielles Handbuch (de) - pack und unpack Python: struct - Strings as packed binary data |
|
|