2010-02-18 12 views
5

Me gustaría escribir un trazador de líneas Perl para decodificar una línea de caracteres ASCII codificados como números hexadecimales (por ejemplo, la línea 48 54 54 50 debe decodificarse como HTTP). Se me ocurrió esto:¿Cómo puedo usar un trazador de líneas Perl para decodificar una cadena ASCII codificada en hexadecimal?

perl -nE 'say map(chr, map { qq/0x$_/ } split)' 

Se imprime una línea en blanco. ¿Qué estoy haciendo mal y cómo lo escribirías?

+1

'perl -lnE 'y/// d; decir paquete "H *", $ _ '' – hobbs

Respuesta

6

Es su truco qq/0x$_/ que no funciona. chr espera un número como argumento, pero obtiene la cadena literal "0x48". Use la función hex para convertir 48 en un número decimal, como datageist en his answer.

Esto funciona para mí:

echo '48 54 54 50' | perl -nE 'say map(chr, map { hex } split)' 
+1

En one-liners solo funciona con '-E' (en lugar de' -e'), pero supongo que ya lo descubrió. Seguramente supera 'print" $ _ \ n "'. – zoul

+0

Gracias por señalarlo, tuve que volver y leer el perldoc una vez más: D –

+1

Su 'map()' se ve terriblemente inconsistente. ¿Pasa algo mal con 'map (chr, map (hex, split))'? –

6

Esto funciona:

echo '48 54 54 50' | perl -nE 'say map{chr(hex)} split' 

Estoy asumiendo que desea alimentar los datos de STDIN.

+0

Gracias, no sabía 'hex '. – zoul

+0

De nada. Gracias por corregir el formato en la publicación. :) – datageist

3

Juego perlgolf?

-ple y/0-9A-Fa-f//cd;$_=pack"H*",$_ 
-ple $_=pack"H*",$_,join"",split 
-nE say map chr hex,split 
-naE say map chr hex,@F 
6

Como siempre con Perl TIMTOWTDI.

Pensé en enviar varias opciones, y mostrar cómo se verían si se escribieran normalmente. Si desea saber más sobre las opciones de línea de comando, perldoc perlrun es un recurso útil.


Todos estos resultados la misma cosa. Con la excepción de que algunos de ellos no imprimen una nueva línea al final.

echo '48 54 54 50' | perl -0x20 -pe'$_=chr hex$_' 
echo '48 54 54 50' | perl -0x20 -ne'print chr hex$_' 
echo '48 54 54 50' | perl -0777 -anE'say map chr,map hex,@F' 
echo '48 54 54 50' | perl -0777 -anE'say map{chr hex$_}@F' 
echo '48 54 54 50' | perl -0apple'$_=chr hex$_' -0x20 
echo '48 54 54 50' | perl -apple'$_=join"",map{chr hex}@F' 
echo '48 54 54 50' | perl -lanE'say map{chr hex}@F' 

A continuación se muestran algunos de los ejemplos que se verían si se escribieran normalmente. Si quieres saber qué hace el resto de ellos, definitivamente mira perldoc perlrun.


perl -0x20 -pe'$_=chr hex$_' 

Este es uno es bastante sencillo. Es quizás el mejor ejemplo aquí, y también es el más corto. Finge que los espacios se usan para separar líneas, de modo que solo hay una letra para tratar dentro del ciclo.

# perl -0x20 -pe'$_=chr hex$_' 
$/ = " "; # -0 (input separator) 
while(<>){ 
    $_ = chr hex $_; 
} continue { 
    print $_; 
} 

perl -0apple'$_=chr hex$_' -0x20 

éste tiene algunas opciones de línea de comandos que no hacen nada útil.

  • La primera opción es -0 allí para que -l establece el separador de salida a una cadena vacía. que es el predeterminado para el separador de salida.
  • Hay dos opciones de -p donde uno habría sido suficiente.
  • La opción -a configura la matriz @F, pero en realidad no la usamos.

Básicamente he usado -a-l y un segundo -p por lo que las opciones significarían manzana. De lo contrario, este es el mismo que el último ejemplo.

echo '48 54 54 50' | perl -0x20 -pe'$_=chr hex$_' 
# perl -0apple'$_=chr hex$_' -0x20 
$/ = ""; # -0 (input separator) 
$\ = $/; # -l (output separator) 
$/ = " "; # -0x20 (input separator) 
while(<>){ 
    @F = split " ", $_; # -a (unused) 
    $_ = chr hex $_; 
} continue { 
    print $_; 
} 

perl -lanE'say map{chr hex}@F' 

que pensé que ya se sueltan de manzana, que bien podría significar Lane.

  • -l no es muy útil, porque ya estamos usando say.
  • Usado -E en lugar de -e para que podamos usar say.
# perl -lanE'say map{chr hex}@F' 
$\ = $/; # -l (output separator set to "\n") 
while(<>){ 
    @F = split " ", $_; # -a 
    say map { chr hex $_ } @F; 
} 
Cuestiones relacionadas