显示文件的十六进制数 [英] Show Hexadecimal Numbers Of a File

查看:17
本文介绍了显示文件的十六进制数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构建一个 bash 程序,它可以读取一个文件,比如 *.bin 并打印它的所有十六进制数字,就像 'hex' 编辑器所做的那样.我可以从哪里开始?

解决方案

添加了字节流"功能.如果脚本名称包含单词stream"(例如,它是一个符号链接,例如 ln -s bash-hexdump bash-hexdump-stream 并作为 ./bash-hexdump-stream 运行code>),它将输出代表文件内容的连续十六进制字符流.否则它的输出看起来像 hexdump -C.

这需要一些技巧,因为 Bash 并不擅长二进制:

#!/bin/bash# bash-hexdump# 丹尼斯威廉姆森 - 2010-01-04# 回应 http://stackoverflow.com/questions/2003803/show-hexadecimal-numbers-of-a-file# 用法:bash-hexdump 文件如果 [[ -z "$1" ]]然后exec 3<&0 # 读取标准输入[[ -p/dev/stdin ]] ||tty="yes" # 没有管道别的exec 3<"$1" # 读取文件菲# 如果脚本名称包含stream",则输出将是连续的十六进制数字# like hexdump -ve '1/1 "%.2x"'[[ $0 =~ 流 ]] &&nostream=false ||无流=真saveIFS="$IFS"IFS="" # 禁用对 	、
 和空格的解释saveLANG="$LANG"LANG=C# 允许字符 >0x7F字节数=0值计数=0$nostream &&printf "%08x " $bytecount而 read -s -u 3 -d '' -r -n 1 char # -d '' 允许换行,-r 允许 做((字节数++))printf -v val "%02x" "'$char" # ' 技巧见下文[[$tty"==是"&&"$val" == "04" ]] &&break # 在 ^D 上退出echo -n "$val"$nostream &&回声 -n " "((价值数++))如果 [[ "$val" <20 ||"$val" >7e]]然后字符串+ =."# 将不可打印的字符显示为一个点别的字符串+=$char菲如果 $nostream &&(( bytecount % 8 == 0 )) # 在中间添加一个空格然后回声 -n " "菲if (( bytecount % 16 == 0 )) # 每行打印 16 个值然后$nostream &&echo "|$string|"字符串=''值计数=0$nostream &&printf "%08x " $bytecount菲完毕if [[ "$string" != "" ]] # 如果最后一行未满,则将其填充然后长度=${#string}如果 (( 长度 > 7 ))然后((长度 - ))菲(( 长度 += (16 - valcount) * 3 + 4))$nostream &&printf "%${length}s
" "|$string|"$nostream &&printf "%08x " $bytecount菲$nostream &&回声LANG="$saveLANG";IFS="$saveIFS"

撇号技巧记录在此处.相关部分说:

<块引用>

如果前导字符是单引号或双引号,值应为数值的底层代码集单引号后的字符或双引号.

以下是脚本的一些输出,显示了我的 /bin/bash 的前几行以及其他几行:

<前>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 .........|

I want to build a bash program that can read a file, like a *.bin and print all its hexadecimal numbers, as 'hex' editors do. Where I can start?

解决方案

Edit: Added "bytestream" functionality. If the script name contains the word "stream" (e.g. it's a symlink such as ln -s bash-hexdump bash-hexdump-stream and run as ./bash-hexdump-stream), it will output a continuous stream of hex characters representing the contents of the file. Otherwise its output will look like hexdump -C.

It takes a bunch of trickery since Bash isn't really good at binary:

#!/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 	, 
 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
" "|$string|"
    $nostream && printf "%08x  " $bytecount
fi
$nostream && echo

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

The apostrophe trick is documented here. The relevant part says:

If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote.

Here is some output from the script showing the first few lines of my /bin/bash plus a few more:

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.........|

这篇关于显示文件的十六进制数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆