Skip to content

Instantly share code, notes, and snippets.

@syndrill
Created June 9, 2018 06:21
Show Gist options
  • Save syndrill/06c47b82661ff69e8e9d13634b7d039c to your computer and use it in GitHub Desktop.
Save syndrill/06c47b82661ff69e8e9d13634b7d039c to your computer and use it in GitHub Desktop.

Revisions

  1. Usman Abdul Halim created this gist Jun 9, 2018.
    67 changes: 67 additions & 0 deletions bash-hexdump.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    #!/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"