显示文件的十六进制数

发布于 2024-08-16 15:55:46 字数 78 浏览 4 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无声静候 2024-08-23 15:55:46

使用 od 命令:

od -t x1  filename

示例输出:

$ printf '0123456789abcdef0123456789abcdef\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' | od -t x1
0000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 66
*
0000040 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0000060

Use the od command:

od -t x1  filename

Sample output:

$ printf '0123456789abcdef0123456789abcdef\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' | od -t x1
0000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 66
*
0000040 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0000060
心房的律动 2024-08-23 15:55:46

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

由于 Bash 并不擅长二进制,因此需要使用一堆技巧:

#!/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"

撇号技巧已记录在案

如果主角是
单引号或双引号,
value 应为中的数值
的底层代码集
单引号后面的字符
或双引号。

以下是脚本的一些输出,显示了我的 /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.........|

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 \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"

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.........|
骷髅 2024-08-23 15:55:46

你可以用od。 “od -x file” 为什么要重新发明那个轮子?

You could use od. "od -x file" Why reinvent that wheel?

深空失忆 2024-08-23 15:55:46

如果有的话也可以使用 hexdump

hexdump -x /usr/bin/binaryfile

you can also use hexdump if you have it

hexdump -x /usr/bin/binaryfile
抱猫软卧 2024-08-23 15:55:46

获取不带任何格式的原始十六进制字节字符串

当您想要转换数据而不是手动查看数据时,此形式也很有用:

od -An -v -tx1 | tr -d ' \n'

示例:

printf '0123456789abcdef0123456789abcdef\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' | od -An -v -tx1 | tr -d ' \n'

输出:

3031323334353637383961626364656630313233343536373839616263646566000102030405060708090a0b0c0d0e0f

因此没有空格或换行符,只有十六进制。

在 Ubuntu 23.04 上测试。

相关:如何在 bash 中创建仅包含十六进制字符而没有空格的文件的十六进制转储?

Get raw hex byte string without any formatting

This form can also be useful when you want to convert data rather than view it manually:

od -An -v -tx1 | tr -d ' \n'

Example:

printf '0123456789abcdef0123456789abcdef\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' | od -An -v -tx1 | tr -d ' \n'

Output:

3031323334353637383961626364656630313233343536373839616263646566000102030405060708090a0b0c0d0e0f

So no spaces or newlines, just the hex.

Tested on Ubuntu 23.04.

Related: How to create a hex dump of file containing only the hex characters without spaces in bash?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文