Tom: Funktion "pack()"

Beitrag lesen

Hi Kaepten

Mit den pack/unpack-Funktionen habe ich gerade kürzlich viele mühsame Stunden verbracht (grumml).

Das Hauptproblem liegt dabei bei Perl in der Repräsentation von Zahlen im Speicher:

Zum Beispiel die Zahl 128 wird _nicht_ als ein Byte mit der Bitfolge '10000000' im Speicher abgelegt, sondern als 3-Byte-Skalar mit der Bitfolge '00110001 00110010 00111000', wobei jedes Byte dem Ascii-Wert der jeweiligen Zahl entspricht (Zahl 1 = Ascii 49, Zahl 2 = Ascii 50, ...).

Für irgendwelche Zahlen- oder Bit-Operationen werden die Sklare (sofern möglich) implizit wieder in das richtige Format umgewandelt. Darum stört diese Phänomen in der Regel nicht.

Bekommt man jedoch aus einer anderen Datenquelle einen binären Datenstrom, der die Zahl 128 als '10000000' enthält, muss dieser Wert mit der unpack-Funktion in ein Perl-Skalar umgewandelt werden. Dies geschieht mit der Funktion:

$PerlSkalar = unpack("C", $binärWert);

$binärWert enthält die binäre Repräsentation eines Wertes (z.B. '10000000')
  $PerlSkalar enthält danach den Skalar mit der Zahl 128 (in drei Bytes)

Die Pack-Funktion funktioniert genau andersrum, dort wird ein Perl-Skalar in eine binäre (oder andere) Repräsentation umgesetzt.

Die Art der Repräsentation hängt vom Template in der pack-Funktion ab (das erste Funktionsargument). Dabei bedeutet das "C" das ein unsigned-char (wie in der Programmiersprache C) zurückgegeben werden soll, was einem 8-Bit-Wert ohne Vorzeichen entspricht (z.B.'10000000' für 128). Es gibt noch viele weitere Templates, diese können in der Perldokumentation im Kapitel perlfunc unter pack() nachgeschlagen werden.

Entsprechend wird in Deinem Beispiel ein hexadezimaler Datenstrom (nach Perl-Notation) 2-zeichenweise in ein binären Bytestrom umgesetzt (z.B. wird 'AF' zum Byte (unsigned-char) '10101111' ).

Grüsse

Tom