2010-03-11 11 views

Antwort

4

Die Schritte sind:

  1. Extract Paare von hexadezimalen Zeichen aus der Zeichenfolge.
  2. Konvertieren Sie jedes Paar in eine Dezimalzahl.
  3. Packen Sie die Nummer als Byte.

Zum Beispiel:

use strict; 
use warnings; 

my $string = 'AA55FF0102040810204080'; 
my @hex = ($string =~ /(..)/g); 
my @dec = map { hex($_) } @hex; 
my @bytes = map { pack('C', $_) } @dec; 

Oder ausgedrückt kompakten:

use strict; 
use warnings; 

my $string = 'AA55FF0102040810204080'; 
my @bytes = map { pack('C', hex($_)) } ($string =~ /(..)/g); 
+0

Dank, wie ich von @bytes bespannen den Rückwärtsbetrieb tun konnte – ron

+0

Dies nicht richtig funktioniert. Es packt nach: aa: 20: 55: 20: ff: 20: 01: 20: 02: 20: 04: 20: 08: 20: 10: 20: 20: 20: 40: 20: 80 Warum alle 20s in Dort??? – poosliver

+0

@poosliver: Die gepackten Daten enthalten nicht druckbare Zeichen. Was Sie sehen, hängt davon ab, wie Sie es gedruckt haben; Ich weiß nicht, was du getan hast. Der Wert von "@ Bytes", wie er von Data :: Dump (der Escape-Sequenzen für nicht druckbare Zeichen verwendet) gedruckt wird, ist "\ xAA", "U", "\ xFF", "\ 1", "\ 2" , "\ 4", "\ b", "\ 20", "", "\ @", "\ x80" '. –

21
my $bytes = pack "H*", $hex; 

Siehe perlpacktut für weitere Informationen.

+6

Ich hasse dieses Tutorial. Warum muss es so kompliziert sein? Warum geben sie mein $ s = pack ('H2' x 10, map {"3 $ _"} (0..9)); als das 'Gegenteil' zu meinem ($ hex) = auspacken ('H *', $ mem); Ich denke ernsthaft, dass sie die Dinge gerne so viel wie möglich zusammenfassen. – Myforwik

1

Ich habe die Zeichenfolge:

61 62 63 64 65 67 69 69 6a

, die ich als Hex-Werte interpretieren wollen, und diejenigen, die als ASCII-Zeichen angezeigt werden (diese Werte sollten die Zeichenfolge „abcdefghij“ reproduzieren).

Normalerweise versuche ich, wie diese schnell etwas zu schreiben:

$ echo "61 62 63 64 65 67 69 69 6a" | perl -ne 'print "$_"; print pack("H2 "x10, $_)."\n";' 
61 62 63 64 65 67 69 69 6a 
a 

... und dann frage ich mich, warum bekomme ich nur ein Zeichen zurück :)

Lassen Sie mich zunächst aufschreiben, dass die Zeichenfolge ich habe, kann auch als die hex-Werte von Bytes dargestellt wird, dass sie im Speicher in Anspruch nehmen:

$ echo -n "61 62 63 64 65 67 68 69 6a" | hexdump -C 
00000000 36 31 20 36 32 20 36 33 20 36 34 20 36 35 20 36 |61 62 63 64 65 6| 
00000010 37 20 36 38 20 36 39 20 36 61     |7 68 69 6a| 
0000001a 

_ (NB: im Wesentlichen, ich will „c onvert“die oben Bytewerte im Speicher als Eingang an dieser unter einem, wenn sie von hexdump angesehen:

$ echo -n "abcdefghij" | hexdump -C 
00000000 61 62 63 64 65 66 67 68 69 6a     |abcdefghij| 
0000000a 

... die ist, wie die ursprünglichen Werte für die Eingabezeichenfolge hex erhalten wurden. ) _

Nun, das Pack/Unpack Tutorial (AKA How the System Stores Data) stellt sich heraus, ist das hilfreich für mich, wie es erwähnt:

Die Pack-Funktion eine Vorlage Zeichenfolge und eine Liste von Werten akzeptiert [...]

$rec = pack("l i Z32 s2", time, $emp_id, $item, $quan, $urgent);

Es gibt eine skalare die Liste der gespeicherten Werte entsprechend den Formaten angegeben in der Vorlage, die [...]

$rec würde Folgendes enthalten (erste Zeile in Dezimal, zweite in Hex, dritte als Zeichen, wo zutreffend).Rohrzeichen geben Feldgrenzen an.

 Offset Contents (increasing addresses left to right) 
     0 160 44 19 62| 41 82 3 0| 98 111 120 101 115 32 111 102 
       A0 2C 13 3E| 29 52 03 00| 62 6f 78 65 73 20 6f 66 
              | b o x e s  o f

heißt, in meinem Fall ist, ist $_ eine einzelne String-Variable - während pack erwartet als Eingabe eine Liste mehrerer solcher 'single' Variablen (zusätzlich zu einer Formatierungsvorlage Zeichenfolge); und gibt wieder eine 'single' Variable aus (was aber ein großer Teil des Speichers sein könnte!). In meinem Fall, wenn die Ausgabe "single" Variable enthält den ASCII-Code in jedem Byte im Speicher, dann bin ich alle gesetzt (ich könnte einfach die Ausgabe-Variable direkt dann drucken).

So, um eine Liste von Variablen aus dem $_ String zu erhalten, kann ich einfach split es im Raum Zeichen - aber Anmerkung:

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2", split(/ /, $_))."\n";' 
61 62 63 64 65 67 68 69 6a 
a 

... die Menge der Elemente pack sein ed muss angegeben werden (sonst erhalten wir wieder nur ein Zeichen zurück); dann arbeitet entweder diese Alternativen:

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2"x10, split(/ /, $_))."\n";' 
61 62 63 64 65 67 68 69 6a 
abcdeghij 

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("(H2)*", split(/ /, $_))."\n";' 
61 62 63 64 65 67 68 69 6a 
abcdeghij