hexdump 命令
一点感想:自从学习 Shell 脚本编程以来,有时候会觉得,使用图形化界面的工具实现一个稍微复杂的操作过于麻烦,并且如果你学习过 Vim 的基本操作和哲学思想后,就会了解命令行的组合可以比图形界面上有限的菜单,按钮能做更过的事情,即实现高度的定制化。
简单介绍
hexdump 工具可以将指定的文件或标准输入,以用户指定的格式进行展示,打印到控制台,提供了很多选项(options),如打印出对应字符的八进制,十六进制
基本选项
-b 八进制
1 | -b One-byte octal display. Display the input offset in hexadecimal, followed by sixteen space-separated, three column, zero-filled, bytes of input data, in octal, per line. |
每行首先以十六进制展示输入偏移量,然后将输入的每个字节以八进制展示 (占 3 位,不足 3 位的用 0 填充),并以空格分隔
1 | $ echo -n 'hello' | hexdump -b |
-c 字符
1 | -c One-byte character display. Display the input offset in hexadecimal, followed by sixteen space-separated, three column, space-filled, characters of input data per line. |
每行首先以十六进制展示输入偏移量,然后展示输入的每个字符 (占 3 位,不足 3 位的用空格填充),并以空格分隔
1 | $ echo -n 'hello' | hexdump -c |
-C 十六进制+ASCII字符
1 | -C Canonical hex+ASCII display. Display the input offset in hexadecimal, followed by sixteen space-separated, two column, hexadecimal bytes, followed by the same sixteen bytes in %_p format enclosed in ``|'' characters. |
每行首先以十六进制展示输入偏移量,然后展示每个字节的十六进制,随后是包含在两个 |
中的对应的字符,非打印字符以 .
展示
1 | $ echo -n 'hello' | hexdump -C |
-C
选项应该是比较常用的,比较方便对比字符与对应的十六进制
-d 两个字节的十进制
1 | -d Two-byte decimal display. Display the input offset in hexadecimal, followed by eight space-separated, five column, zero-filled, two-byte units of input data, in unsigned decimal, per line. |
每行首先以十六进制展示输入偏移量,然后将输入数据中的每两个字节作为一个单元,并展示他们组合成的无符号十进制数
1 | $ echo -n 'hello' | hexdump -d |
注意:两个字节组合的顺序与字符的顺序相反,例如 he
, h
的十六进制是 0x68
,e
的十六进制是 0x65
, 但是字节组合的顺序是 0x6568
, 对应的十进制就是上面结果中的 2590
1 | $ echo $((16#6568)) |
-x 两个字节的十六进制
1 | -x Two-byte hexadecimal display. Display the input offset in hexadecimal, followed by eight, space separated, four column, zero-filled, two-byte quantities of input data, in hexadecimal, per line. |
和 -d
类似
1 | $ echo -n 'hello' | hexdump -x |
-n 只处理 n 个字节
1 | -n length Interpret only length bytes of input. |
-v 展示所有的字符
1 | -v Cause hexdump to display all input data. Without the -v option, any number of groups of output lines, which would be identical to the immediately preceding group of output lines (except for the input offsets), are |
格式化
-e 格式化字符串
1 | -e format_string |
指定格式化字符串
-f 包含格式化字符串的文件
1 | -f format_file |
一个格式化字符串由任意多个格式化单元(format unit)组成,每个格式化单元以空格分隔。一个格式化单元最多由三个部分组成:迭代次数(iteration count),字节个数 (byte count),以及格式字符串 (format)
迭代次数:可选的正整数,默认为1, 表示格式字符串要被应用多少次
字节个数: 可选的正整数. 如果指定了,它定义了每次应用格式字符串时,需要使用多少个字节
如果指定了迭代次数和(或)字节个数,需要使用 /
来加以区分,如 1/4
,/4
格式字符串:必须指定,并且要包含在双引号中 ""
, 类似于 fprintf
中的格式字符串, 支持单个字符的转义序列:
1 | NUL \0 |
如包含一个格式化单元的格式化字符串:'4/1 "%_p"'
, 4 表示迭代次数,1表示每次使用一个字节,%_p
为格式字符串
也支持额外的转换字符串:
_a[dox]
展示输入偏移量d
,o
,x
分表表示十进制,八进制和十六进制_A[dox]
与_a[dox]
行为一致,但是只执行一次,当所有的输入数据都被处理了_c
以默认的字符集打印出输入字符,非打印字符以八进制展示(占 3 位,不足三位用 0 填充),如果该字符支持转义序列,则会以转义序列的形式展示,如\n
_p
以默认的字符集打印出输入字符. 非打印字符会被展示成.
_u
打印出ASCII
字符,控制字符会被展示成如下的名称(小写):
1 | 000 NUL 001 SOH 002 STX 003 ETX 004 EOT 005 ENQ |
每个格式字符串需要使用字节个数等于所有格式化单元使用的字节个数加起来,每个格式化单元使用的字节个数 = 迭代次数 * 字节个数 (或者没有指定字节个数,格式单元需要的字节个数)
1 | echo "ABCDEFGH" | hexdump -e '4/1 "%_p"' |
上述中的格式化字符串需要使用的字节个数 = 4 * 1
输入数据,是以 “数据块”(blocks) 的形式处理的,一个数据块定义为所有格式化字符使用的最大字节数
指定格式化字符串的列子
打印输入数据的十六进制
1 | $ echo hello | hexdump -v -e '/1 "%02X "' ; echo |
打印输入数据的十六进制及字符
1 | % echo hello | hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' |
打印十六进制,并加上前缀 x
1 | # hex with preceding 'x' |
打印十六进制,每行一个字节
1 | # one hex byte per line |
带偏移量
1 | # byte# & ASCII with control chars |
每行只打印一个字节对应的十六进制,以及对应的 ASCII 字符,行首打印偏移量,即序号
1 | $ echo "ABCDEFG" | hexdump -e '/1 "%02_ad# "' -e '/1 "%02X "' -e '/1 " %_u\n"' |
7C1C分隔符示例
1 | # char.dat |
1 | # a table of byte#, hex, decimal, octal, ASCII |