2010-03-11 6 views

Répondre

4

Les étapes sont les suivantes:

  1. paires d'extrait de caractères hexadécimaux de la chaîne.
  2. Convertissez chaque paire en un nombre décimal.
  3. Empilez le nombre sous la forme d'un octet.

Par exemple:

use strict; 
use warnings; 

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

Ou, exprimé de manière plus compacte:

use strict; 
use warnings; 

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

Merci Comment pourrais-je faire l'opération inverse de @bytes à chaîne – ron

+0

Cela ne fonctionne pas correctement. Il contient: aa: 20: 55: 20: ff: 20: 01: 20: 02: 20: 04: 20: 08: 20: 10: 20: 20: 20: 40: 20: 80 Pourquoi tous les 20 dans Là??? – poosliver

+0

@poosliver: Les données compressées contiennent des caractères non imprimables. Ce que vous voyez dépendra de la manière dont vous l'avez imprimé. Je ne sais pas ce que tu as fait. La valeur de '@ bytes' telle qu'elle est imprimée par Data :: Dump (qui utilise des séquences d'échappement pour les caractères non imprimables) est' "\ xAA", "U", "\ xFF", "\ 1", "\ 2" , "\ 4", "\ b", "\ 20", "", "\ @", "\ x80" '. –

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

Voir perlpacktut pour plus d'informations.

+6

Je déteste ce tutoriel. Pourquoi est-ce que ça doit être trop compliqué? Pourquoi donnent-ils mon $ s = pack ('H2' x 10, map {"3 $ _"} (0..9)); comme le 'contraire' de mon ($ hex) = décompresser ('H *', $ mem); Je pense sérieusement qu'ils aiment autant convoluer les choses que possible. – Myforwik

1

J'ai la chaîne:

« 61 62 63 64 65 67 69 69 6a »

que je veux interpréter comme des valeurs hexagonales, et afficher les comme caractères ASCII (ces valeurs doivent reproduire la chaîne de caractères « abcdefghij »).

En général, j'essaie d'écrire quelque chose de rapide comme ceci:

$ 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 

... et je me demande, pourquoi dois-je obtenir un seul caractère retour :)

D'abord, permettez-moi de noter que la chaîne je, peut également être représenté comme les valeurs hexa d'octets qu'il prend en mémoire:

$ 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: Essentiellement, je veux « c onvert » les valeurs d'octets ci-dessus dans la mémoire comme entrée, à ceux-ci-dessous, si vu par hexdump:

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

... ce qui est de savoir comment les valeurs d'origine pour la chaîne hexagonale d'entrée ont été obtenus. ) _

Eh bien, ce Pack/Unpack Tutorial (AKA How the System Stores Data) se révèle est le plus utile pour moi, car il mentionne:

La fonction pack accepte une chaîne de modèle et une liste de valeurs [...]

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

il renvoie un scalaire contenant la liste des valeurs mémorisées en fonction des formats spécifiés dans le modèle [...]

$rec contient les éléments suivants (première ligne en décimal, deuxième en hexadécimal, troisième en caractères, le cas échéant).Les caractères de tuyau indiquent les limites de champ.

 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

C'est, dans mon cas, $_ est une seule variable de chaîne- alors pack en entrée un liste de plusieurs variables telles « unique » (en plus d'une chaîne de modèle de mise en forme) et renvoie à nouveau une variable 'unique' (qui pourrait, cependant, être un morceau important de mémoire!). Dans mon cas, si la variable de sortie 'single' contient le code ASCII dans chaque octet en mémoire, alors je suis tout ensemble (je pourrais simplement imprimer la variable de sortie directement, alors).

Ainsi, afin d'obtenir une liste de variables de la chaîne $_, je peux simplement split il à l'enseigne de l'espace - cependant, note:

$ 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 

... ce montant d'éléments à pack ed doit être spécifié (sinon nous ne récupérons qu'un seul caractère); puis, l'une de ces alternatives fonctionnent:

$ 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 
Questions connexes