2010-01-05 19 views
14

Quiero construir un programa bash que pueda leer un archivo, como un * .bin e imprimir todos sus números hexadecimales, como lo hacen los editores 'hexadecimales'. Donde puedo comenzar?Mostrar números hexadecimales de un archivo

+0

http://unix.stackexchange.com/questions/10826/shell-how- to-read-the-bytes-of-a-binary-file-and-print-as-hexadecimal –

Respuesta

20

Editar: Agregado funcionalidad "bytestream". Si el nombre del script contiene la palabra "stream" (por ejemplo, es un enlace simbólico como ln -s bash-hexdump bash-hexdump-stream y se ejecuta como ./bash-hexdump-stream), generará una secuencia continua de caracteres hexadecimales que representan el contenido del archivo. De lo contrario, su salida se verá como hexdump -C.

Se necesita un montón de engaños ya Bash no es muy bueno en binario:

#!/bin/bash 
# bash-hexdump 
# by Dennis Williamson - 2010-01-04 
# in response to http://stackoverflow.com/questions/2003803/show-hexadecimal-numbers-of-a-file 
# usage: bash-hexdump file 

if [[ -z "$1" ]] 
then 
    exec 3<&0       # read stdin 
    [[ -p /dev/stdin ]] || tty="yes" # no pipe 
else 
    exec 3<"$1"   # read file 
fi 

# if the script name contains "stream" then output will be continuous hex digits 
# like hexdump -ve '1/1 "%.2x"' 
[[ $0 =~ stream ]] && nostream=false || nostream=true 

saveIFS="$IFS" 
IFS=""      # disables interpretation of \t, \n and space 
saveLANG="$LANG" 
LANG=C      # allows characters > 0x7F 
bytecount=0 
valcount=0 
$nostream && printf "%08x " $bytecount 
while read -s -u 3 -d '' -r -n 1 char # -d '' allows newlines, -r allows \ 
do 
    ((bytecount++)) 
    printf -v val "%02x" "'$char" # see below for the ' trick 
    [[ "$tty" == "yes" && "$val" == "04" ]] && break # exit on ^D 
    echo -n "$val" 
    $nostream && echo -n " " 
    ((valcount++)) 
    if [[ "$val" < 20 || "$val" > 7e ]] 
    then 
     string+="."     # show unprintable characters as a dot 
    else 
     string+=$char 
    fi 
    if $nostream && ((bytecount % 8 == 0))  # add a space down the middle 
    then 
     echo -n " " 
    fi 
    if ((bytecount % 16 == 0)) # print 16 values per line 
    then 
     $nostream && echo "|$string|" 
     string='' 
     valcount=0 
     $nostream && printf "%08x " $bytecount 
    fi 
done 

if [[ "$string" != "" ]]   # if the last line wasn't full, pad it out 
then 
    length=${#string} 
    if ((length > 7)) 
    then 
     ((length--)) 
    fi 
    ((length += (16 - valcount) * 3 + 4)) 
    $nostream && printf "%${length}s\n" "|$string|" 
    $nostream && printf "%08x " $bytecount 
fi 
$nostream && echo 

LANG="$saveLANG"; 
IFS="$saveIFS" 

El truco apóstrofe se documentó here. La parte pertinente dice:

Si el personaje principal es un comilla simple o doble cotización, el valor será el valor numérico en el conjunto de códigos subyacente del personaje después de la comilla simple o comillas dobles

Aquí es un poco de salida del script que muestra las primeras líneas de mi /bin/bash además de unos cuantos más:

 
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 
00000010 02 00 03 00 01 00 00 00 e0 1e 06 08 34 00 00 00 |............4...| 
00000020 c4 57 0d 00 00 00 00 00 34 00 20 00 09 00 28 00 |.W......4. ...(.| 
00000030 1d 00 1c 00 06 00 00 00 34 00 00 00 34 80 04 08 |........4...4...| 
. . . 
00000150 01 00 00 00 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 |..../lib/ld-linu| 
00000160 78 2e 73 6f 2e 32 00 00 04 00 00 00 10 00 00 00 |x.so.2..........| 
00000170 01 00 00 00 47 4e 55 00 00 00 00 00 02 00 00 00 |....GNU.........| 
+0

Por cierto, el formato de salida de este script es el mismo que 'hexdump -C' o' hd'. –

+1

Es bueno ver a alguien haciendo cosas inusuales e incluso binarias con bash. Pieza de código muy interesante! – ajaaskel

+0

por qué usar skript complejo cuando puedes hacerlo con pocos comandos – nkvnkv

21

Utilice el comando od,

od -t x1 filename

+0

¿Es 'od' un programa Linux o una función bash? Lo siento, soy un principiante. –

+2

@Nathan Campos: puedes averiguar usando 'which od', si obtienes el nombre de un programa, entonces es un programa externo (para 'od', probablemente lo sea). –

+4

bastante estándar en Unixes, ha existido desde el comienzo de los tiempos. –

3

Usted podría utilizar od. "od -x file" ¿Por qué reinventar esa rueda?

1

también se puede utilizar hexdump si lo tiene

hexdump -x /usr/bin/binaryfile 
Cuestiones relacionadas