hexyl 是一个命令行十六进制查看器,主程序 1069056 字节。给它一个文件,它按 16 字节一行打出偏移量、十六进制和右侧 ASCII 列,字节按可读类别上不同颜色。

它解决的问题是「看一眼二进制里到底是什么」。改过的配置或者损坏的图片头,文本编辑器打开都是一堆乱码,用它对一遍十六进制就能判断文件类型对不对。

这次拿一张 27802 字节的 PNG 看了前 160 字节,又把 6235136 字节的 fzf.exe 整个倒出来计时,量了输出膨胀倍数和三种颜色分类。

解压出来 6 个文件

官方 zip 430403 字节,解开是 6 个文件共 1100748 字节。主程序 1069056 字节,剩下三个是 LICENSE 与 README 这类文本。

项目字节说明
zip 整体430403官方 msvc 包
hexyl.exe1069056主程序,纯命令行
目录合计11007486 个文件
版本命令169 毫秒后两次 126 / 118 毫秒

版本命令连跑三次

# 三次耗时 169 / 126 / 118 毫秒
hexyl --version
hexyl 0.17.0

第一行 169 毫秒,后两次 126 和 118 毫秒,差的那 50 毫秒在首次加载 exe。1069056 字节的体积起进程本来就快,这个数字没有多少优化空间。

它没有图形界面

参数就十几个:-n 读多少字节 / -s 跳过多少字节 / --color 控制上色 / -v 关掉重复行压缩。所有输出走标准输出,重定向和接管道都正常。

看一张 PNG 的前 160 字节

命令是 hexyl -n 160 shots\shiori_list.png,出来 10 行数据加一个边框。第一行开头是 89 50 4e 47 0d 0a 1a 0a,这是 PNG 的固定文件头。

位置实测值含义
第 1 行前 8 字节89 50 4e 47 0d 0a 1a 0aPNG 签名,八个字节固定
右侧 ASCII 列.PNG....可打印字符原样显示,其余用点
第 2 行00 00 00 0d 49 48 44 52IHDR 块,长度 13 字节
单行字节数16左右两组各 8 字节,中间留空

四种颜色对应四类字节

偏移量是一色,空字节一色,可打印 ASCII 一色,其他不可打印字节一色。扫一眼颜色分布就知道这个文件里有没有大量填充的 00,或者是不是纯文本误改了后缀。

hexyl 查看一张 PNG 前 160 字节:10 行十六进制,偏移量单独一色,右侧 ASCII 列显示 .PNG....IHDR

右侧那一列不能全信

ASCII 列只显示 0x20 到 0x7e 之间的字符,其他一律打成点。中文这类多字节内容在右侧全是点,得看中间的十六进制值才对得上。

整个文件倒出来是 89074664 字节

拿 6235136 字节的 fzf.exe 做样本,不加 -n 直接倒完,三次是 855 / 874 / 914 毫秒,输出 388865 行共 89074664 字节。

项数值说明
源文件字节6235136fzf.exe 本体
输出字节8907466414.3 倍膨胀
输出行数388865加 -v 是 389698 行
理论行数3896966235136 除以 16
被压缩的行831连续重复内容折成星号
倒完耗时855 毫秒三次 855 / 874 / 914

默认会把重复行压成一个星号

6235136 字节按每行 16 字节算应该是 389696 行,实际只出来 388865 行,差的 831 行是连续重复内容被折成单个星号。加 -v 关掉这个压缩,行数回到 389698,正好是 389696 行数据加两条边框。

十四倍膨胀是必然的

每 16 个字节要写成 8 个偏移字符加 32 个十六进制字符,中间还要插进去 16 个空格,最后补一列 ASCII。6235136 字节就这样变成 89074664 字节。

先用 -n 截一段

# 只看前 256 字节,18 行,4006 字节
hexyl -n 256 文件
# 跳过前 1 MB,看后面 4 KB
hexyl -s 1048576 -n 4096 文件

256 字节出来 18 行 4006 字节。真要看大文件的中段,-s 跳偏移比先倒完再翻页快得多,倒完 6235136 字节要 855 毫秒。

一行 16 字节是怎么排的

输出的每一行固定 16 个字节,分左右两组各 8 个,中间空一格方便数。最左边那 8 个字符是这一行在文件里的起始偏移,十六进制表示。

0000000000 │ 89 50 4e 47 0d 0a 1a 0a │ 00 00 00 0d 49 48 44 52 │ .PNG....IHDR
区段宽度内容
偏移列8 个字符从 00000000 起,每行加 10
十六进制列32 个字符16 个字节,每个两位
分隔空格17 个字节之间 15 个加左右各一
ASCII 列16 个字符0x20 到 0x7e 原样,其余打成点

偏移量那一列是最有用地标

第一行偏移 00000000,第二行 00000010,第十五行的偏移是 000000e0。报错信息里给了一个十六进制偏移时,按这个步长心算就知道该翻到第几行。

-n 支持带单位写

-n 4KiB 等于 4096 字节,-n 0xff 等于 255 字节。写 -n 256 出来 18 行,其中 16 行数据加两条边框。

装之前先确认三件事

它不写注册表,也不建配置目录,解压就能用。要确认的是终端能不能正确显示颜色,以及要不要把它加进 PATH。

项本次实测说明
系统Windows 10 22H2(19045.6466)官方 msvc 包
终端cmd.exe 开虚终端转义码能解析才上色
注册表不写目录拷走就完成迁移
授权MIT 或 Apache-2.0可商用,可再分发

控制台不开虚终端就是一堆方括号

cmd 里直接跑,输出会是 ←[90m 开头的一串字符,颜色不生效。这个现象不是程序坏了,是控制台没有启用转义序列解析,换个支持虚终端的终端就好。

它不改文件

hexyl 只读不写。参数里没有写回或者编辑的选项,看错文件也不会留下任何痕迹,这一点对排查线上问题很关键。

三个真会踩的地方

颜色默认是开着的

--color 的默认值是 always,不是 auto。重定向到文件时转义序列照样写进去,实测管道输出里带上百个 033 字节。要干净的文本加 --color=never。

-n 的单位是字节不是行

-n 256 表示读 256 个字节,出来 18 行。想按行截取要自己算,16 字节一行,256 除以 16 得 16 行数据加边框。

ASCII 列对中文没有意义

UTF-8 的中文一个字符占 3 字节,全在 0x80 以上,右侧 ASCII 列全是点。判断中文内容要看中间的十六进制值,不要指望右边那一列。

什么场景值得上

排查「文件类型对不对」最有用。图片打不开或者接口返回的 body 是乱码,先看前 16 字节的文件头,比反复重下文件快。一张 PNG 的前 160 字节只要 10 行。

反过来,日常只处理文本文件的人装它没什么机会用。type 和编辑器已经够看,十六进制视图只有在怀疑字节本身的时候才派得上用场。

项目数值
exe 字节1069056
zip 字节430403
看 160 字节10 行输出
倒完 6235136 字节855 毫秒 / 388865 行
输出膨胀倍数14.3