使用 hexdump 输出 64 位整数

Output 64 bit integer with hexdump

我目前正在处理一些二进制数据。 为了检查和调试我的应用程序以前生成的数据,我使用 hexdump,面临 hexdump 似乎无法提取 64 位整数字段的障碍。 给定以下最小示例:

#include <iostream>
#include <fstream>
#include <cstdint>

int main(int argc, char** argv){
    std::ofstream os("tmp.bin", std::ios::out | std::ios::binary);
    uint64_t x = 7;
    os.write((char*)&x,sizeof(uint64_t));
    os.close();
    return 0;
}

我在我的系统上执行了一个简单的 hexdump:

hexdump tmp.bin

> 0000000: 0007 0000 0000 0000
> 0000008:

现在尝试提取 64 位宽度的 unsigned int 产量:

hexdump -e '/8 "%u"' tmp.bin

> hexdump: bad byte count for conversion character u

按照写得好hexdump-manual by David Mair应该可以做到,但是我没有成功

我错过了什么?

我们最终的解决方法如下:

x=`hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME} | awk 'BEGIN{printf "0x"}{print }'`
echo $(($x))

各部分说明:

  • 从文件 {FILENAME} 中提取 64 位整数值的八个字节 作为两个四字节块打印为十六进制编码值。

    hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME}
    
  • 反转两个块的字节顺序并将其打印为表示二进制值的单个八字节块。 Prepend 0x 用于后续处理。

    awk 'BEGIN{printf "0x"}{print }
    
  • 将十六进制表示保存到x中供bash计算。

    x=`....`
    
  • 让bourneshell解释输出64位整型变量的十六进制编码值(这里需要前面加上0x ).

    echo $(($x))
    

也可以使用 sed。以下匹配 8 字节十六进制整数并交换它们。同样,这仅适用于无符号整数。

hexdump ... | sed 's/0x\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)/0x/'

AFAICT 应该能写得更清楚

hexdump ... | sed 's/0x\([0-9a-f]{8,8}\)\([0-9a-f]{8,8}\)/0x/'

通常使用某些命令行选项(例如 -E)来启用扩展的正则表达式,但至少在 Mac OS X 10.10 上这不起作用。

我不明白为什么这不能开箱即用,但我在打印 64 位整数时遇到了同样的问题,最终从 util-linux 中找到了一个更好的版本:https://github.com/karelzak/util-linux。起初我尝试在 Ubuntu 中安装该软件包,但它没有更新 hexdump,所以我决定尝试这样做 "manually."

工作量有点大,但还算不错。只需使用 git 获取源代码,运行 autogen.sh 脚本,然后 ./configure 然后 make hexdump 编译该程序。在我的笔记本电脑上编译只用了 4 秒。

尝试使用 "od" 命令。 -xL 输出长整数