2010-01-05 13 views
14

Voglio costruire un programma bash in grado di leggere un file, come un * .bin e stampare tutti i suoi numeri esadecimali, come fanno gli editor 'hex'. Dove posso iniziare?Mostra i numeri esadecimali di un file

+0

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

risposta

20

Edit: Aggiunto "bytestream" funzionalità. Se il nome dello script contiene la parola "stream" (ad esempio è un collegamento simbolico come ln -s bash-hexdump bash-hexdump-stream ed è in esecuzione come ./bash-hexdump-stream), verrà generato un flusso continuo di caratteri esadecimali che rappresentano il contenuto del file. In caso contrario, l'output sarà simile a hexdump -C.

ci vuole un po 'di inganno poiché Bash non è veramente bravo a 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" 

Il trucco apostrofo è documentata here. La parte rilevante dice:

Se il protagonista è un single-citazione o virgolette doppie, il valore è il valore numerico in il codeset sottostante del personaggio seguente single-citazione o doppio preventivo.

Ecco alcuni output dello script che mostra le prime righe della mia /bin/bash oltre a un po 'di più:

 
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

A proposito, il formato di output di questo script è lo stesso di 'hexdump -C' o' hd'. –

+1

È bello vedere qualcuno che fa cose insolite e persino binari con bash. Pezzo di codice molto interessante! – ajaaskel

+0

perché usare uno script complesso quando puoi farlo con pochi comandi – nkvnkv

21

Utilizzare il comando od,

od -t x1 filename

+0

È 'od' un programma Linux o una funzione bash? Scusa, sono davvero un principiante. –

+2

@Nathan Campos: puoi scoprire usando 'quale od', se ottieni il nome di un programma, allora è un programma esterno (per' od', probabilmente lo è). –

+4

piuttosto standard in unix, in giro dalla notte dei tempi. –

3

Si potrebbe usare od. "od -x file" Perché reinventare quella ruota?

1

è anche possibile utilizzare hexdump se lo avete

hexdump -x /usr/bin/binaryfile 
Problemi correlati