2010-03-11 23 views

Respuesta

4

Los pasos son:

  1. Extracto de pares de caracteres hexadecimales de la cadena.
  2. Convierta cada par a un número decimal.
  3. Pack el número como un byte.

Por ejemplo:

use strict; 
use warnings; 

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

O, expresado de forma más compacta:

use strict; 
use warnings; 

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

Gracias ¿Cómo podría hacer la operación inversa de la cadena de @bytes a – ron

+0

esto no funciona correctamente. Contiene: aa: 20: 55: 20: ff: 20: 01: 20: 02: 20: 04: 20: 08: 20: 10: 20: 20: 20: 40: 20: 80 Por qué todos los 20 en ¿¿¿ahí??? – poosliver

+0

@poosliver: los datos empaquetados contienen caracteres no imprimibles. Lo que ve dependerá de cómo lo haya impreso; No sé lo que hiciste El valor de '@ bytes' impreso por Data :: Dump (que usa secuencias de escape para caracteres no imprimibles) es' "\ xAA", "U", "\ xFF", "\ 1", "\ 2" , "\ 4", "\ b", "\ 20", "", "\ @", "\ x80" '. –

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

Ver perlpacktut para más información.

+6

Odio ese tutorial. ¿Por qué tiene que ser tan excesivamente complicado? ¿Por qué dan mi $ s = paquete ('H2' x 10, mapa {"3 $ _"} (0..9)); como el "opuesto" a mi ($ hex) = desempaquetar ('H *', $ mem); Creo seriamente que les gusta complicar las cosas tanto como sea posible. – Myforwik

1

que tienen la cadena:

"61 62 63 64 65 67 69 69 6a"

que quiero interpretar como valores hexadecimales, y mostrar los caracteres ASCII como (esos valores deben reproducir la cadena de caracteres "abcdefghij").

Por lo general, trato de escribir algo rápido como esto:

$ 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 

... y entonces me pregunto, ¿por qué recibo un solo personaje volver :)

En primer lugar, permítanme señalar que hasta la cadena que tengo, también se puede representar como los valores hexadecimales de bytes que ocupa en la memoria:

$ 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: en esencia, quiero "c onvert" los valores anteriores bytes en la memoria como entrada, a estos los de abajo, cuando la mire hexdump:

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

... que es como se obtuvieron los valores originales de la cadena hexadecimal de entrada. ) _

Bueno, esto resulta Pack/Unpack Tutorial (AKA How the System Stores Data) es el más útil para mí, ya que menciona:

La función acepta un paquete de plantilla y una lista de valores [...]

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

devuelve un escalar que contiene la lista de los valores almacenados de acuerdo con los formatos especificados en la plantilla [...]

$rec contendría lo siguiente (primera línea en decimal, segunda en hexadecimal, tercera como caracteres cuando corresponda).Los caracteres de tubería indican los límites del campo.

 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

Eso es, en mi caso, $_ es una sola variable cadena - mientras que pack espera como entrada una lista de varios tales variables simples '' (además de una cadena de plantilla de formato); y devuelve una variable 'única' (¡que podría, sin embargo, ser un pedazo considerable de memoria!). En mi caso, si la variable 'simple' de salida contiene el código ASCII en cada byte en la memoria, entonces estoy listo (podría simplemente imprimir la variable de salida directamente, luego).

Por lo tanto, con el fin de obtener una lista de las variables de la cadena $_, puedo simplemente split que en la muestra del espacio - sin embargo, nota:

$ 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 

... esa cantidad de elementos a ser pack ed debe especificarse (de lo contrario, solo recuperamos un carácter); a continuación, cualquiera de estas alternativas de trabajo:

$ 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 
Cuestiones relacionadas