2011-04-20 24 views
27

Ahora estoy haciendo de esta manera:Ascii/Hex convertir en bash

[[email protected]~]# echo Aa|hexdump -v 
0000000 6141 000a        
0000003 
[[email protected]~]# echo -e "\x41\x41\x41\x41" 
AAAA 

Pero no se comporta exactamente como quería,

la forma hexagonal de Aa debe ser 4161, pero la salida es 6141 000a, lo que parece no tener sentido.

y al realizar hexadecimal a ascii, ¿hay alguna otra utilidad para que no necesite el prefijo \x?

Respuesta

40

La razón es porque hexdump por las impresiones de espera predeterminado enteros de 16 bits, no por bytes. Si su sistema los tiene, hd (o hexdump -C) o xxd proporcionará salidas menos sorprendentes; de lo contrario, od -t x1 es una forma POSIX estándar para obtener una salida hexadecimal byte por byte. Puede usar od -t x1c para mostrar tanto los valores hexadecimales como las letras correspondientes.

Si tiene xxd (que se envía con vim), puede usar xxd -r para convertir de nuevo desde hexadecimal (del mismo formato xxd produce). Si solo tiene un hex simple (solo el '4161', que es producido por xxd -p) puede usar xxd -r -p para convertir de nuevo.

+0

'xxd -p -r AAA', esto no funciona, ¿puede recuperar parámetros directamente desde la línea de comandos? – gdb

+6

no ... y la 'r' se convierte de nuevo en hexadecimal, querrías algo como '' echo 4161 | xxd -r -p' 'o' 'echo Aa | xxd -p '' – Random832

12

Para la primera parte, trata

echo Aa | od -t x1 

Imprime byte a byte

$ echo Aa | od -t x1 
0000000 41 61 0a 
0000003 

El 0a es la nueva línea implícita que produce eco.

Use echo -n o printf en su lugar.

$ printf Aa | od -t x1 
0000000 41 61 
0000002 
+1

Cómo convertir el hex de nuevo a ascii? – gdb

11
$> printf "%x%x\n" "'A" "'a" 
4161 
+0

¿Cuál es el formato de '" 'A ""' a "'? – gdb

+0

@gdb: Ver [printf] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html) donde dice: "Si el personaje principal es una comilla simple o una comilla doble, el valor será el valor numérico en el conjunto de códigos subyacente del personaje que sigue la comilla simple o comilla doble ". –

+0

La solución 'printf' de estilo c aquí debe ser la respuesta aceptada. Es el más portátil y el más simple, y se mantiene con el cumplimiento POSIX sin necesidad de herramientas externas que pueden o no estar disponibles. – Yokai

3

No sé cómo loco se ve pero hace el trabajo muy bien

ascii2hex(){ a="[email protected]";s=0000000;printf "$a" | hexdump | grep "^$s"| sed s/' '//g| sed s/^$s//;} 

creado este cuando estaba tratando de ver mi nombre en HEX;) uso ¿cómo se puede utilizar:)

1

aquí un pequeño script que escribí para convertir ascii a hexadecimal. Espero que ayude:

echo '0x'"`echo 'ASCII INPUT GOES HERE' | hexdump -vC | awk 'BEGIN {IFS="\t"} {$1=""; print }' | awk '{sub(/\|.*/,"")}1' | tr -d '\n' | tr -d ' '`" | rev | cut -c 3- | rev 
0

echo añada un retorno de carro al final.

Uso

echo -e 

para eliminar el 0x0A adicional

Además, hexdump no funciona byte por byte como predeterminado. Es por eso que muestra los bytes en una endianess extraña y por qué te muestra un extra de 0x00.

0

acuerdo con http://mylinuxbook.com/hexdump/ se puede utilizar el parámetro de formato hexdump

echo Aa | hexdump -C -e '/1 "%02X"' 

volverá 4161

para añadir un salto de línea extra al final, agregue otro formateador.

PERO: el formato dado anteriormente dará salida del multiplicador de caracteres repetitivos

$ printf "Hello" | hexdump -e '/1 "%02X"' 
48656C* 
6F 

en lugar de

48656c6c6f 
0
Text2Conv="Aa" 
for letter in $(echo "$Text2Conv" | sed "s/\(.\)/'\1 /g");do printf '%x' "$letter";done 

El truco está usando sed para analizar el Text2Conv para formatear, entonces podemos seper comió anf loop usando for.

2

Con bash:

a=abcdefghij  
for ((i=0;i<${#a};i++));do printf %02X \'${a:$i:1};done 

6162636465666768696A

+0

salida incorrecta para algunos caracteres como (espacio, tabulación, \ r, \ n) todos estos caracteres se mostrarán como \ x00 – Giac

1

respuesta de SteinAir anterior era útil para mí - gracias! Y a continuación es una forma en que se inspiró, para convertir cadenas hexadecimales a ASCII:

for h in $(echo "4161" | sed "s/\(..\)/\1 /g"); do printf `echo "\x$h"`;done 
Aa 
-2

iba a escribir esto como un comentario a @ 'S Coombs, pero tenía miedo de que no encajaría y el formato de los comentarios doesn no funciona tan bien

Re:

for h in $(echo "4161" | sed "s/\(..\)/\1 /g"); do printf `echo "\x$h"`;done 

agradable para ASCII, pero creo que el estándar para la mayoría de distribuciones en estos días es UTF-8 (y estaba en muchos antes de 2011). Prácticamente ninguno de los anteriores "hace lo correcto" con la entrada UTF-8. Por ejemplo: el uso de una "estrella" Unicode (U + 2605) el código anterior pone a cabo:

> LC_ALL=en_US.UTF-8  ## making this explicit for this example 
> star="★" 
> hex() { 
    if ((!$#)); then return; fi 
    for ((i=0;i<${#1};i++));do printf %02X \'${$1:$i:1};done 
} 
> hex "$star" 
2605 

Si desea que los bytes UTF-8 hexagonales reales que componen la estrella, es necesario para establecer primero la configuración regional . Como en:

> LC_ALL=C hex "$star" 
E29885 

Si ha mezclado la producción (como minúsculas latino 'a'), la estrella (U + 2605 = '★'), y un "Mathematical Sans-serif pequeña A" (U + 1D5BA = ''), y desea los valores de los caracteres, luego debe codificar la salida en función del valor del carácter. Los que están por debajo de 0x7f, pueden imprimirse como hexadecimales (\ x7f en cadenas bash), pero los que están por debajo de ~ 64K necesitan un \ u2605 (para empezar) y el resto por encima de 64K necesitan los \ U {8 dígitos hexadecimales} o \ U0001D5BA para Math-a, o algo así:

> star='★' math_a='' 
> locale_hex "a$star$math_a" 
\X61\u2605\U0001D5BA 

pero esto sería técnicamente ir 'fuera de lugar' para la pregunta original - pero todavía es algo para estar al tanto de & tener en cuenta. Publicar la solución que genera esa salida sería "demasiado OT-text" para mi comodidad (con suerte esta advertencia no se considera demasiado divergente de la pregunta original, ya que tenía 'ord', 'hex' (y 'chr) similares ') funciones que me dieron que funcionó para ascii, que se confundieron seriamente cuando los valores predeterminados UTF-8 se lanzaron a la mezcla.

Si bien las respuestas anteriores están bien para sistemas ascii, estos se están convirtiendo en bestias raras en estos días, especialmente desde la codificación de caracteres predeterminada para HTML5 = UTF-8.

-2
[email protected]:~$ echo -n The quick brown fox jumps over the lazy dog | python -c "print raw_input().encode('hex')," 
54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67 
[email protected]:~$ echo -n The quick brown fox jumps over the lazy dog | python -c "print raw_input().encode('hex')," | python -c "print raw_input().decode('hex')," 
The quick brown fox jumps over the lazy dog 

se podría hacer con Python3 también, pero de manera diferente, y soy un perro flojo.

+0

' python'! = 'bash' – Yokai

+0

tampoco son' sed', ' hexdump', 'printf',' awk', o 'xxd'. –

+0

es más corto que algunas de las otras soluciones y podría decirse que es más legible. y se convierte en ambos sentidos, desde la línea de comando Bash. No veo tu punto. –