如何使用"cmp"来比较两个二进制文件并找到它们不同的所有字节偏移量?



我希望在Bash脚本循环方面得到一些帮助,它将显示两个二进制文件之间的所有差异,只需使用

cmp file1 file2 

它只显示了我想使用cmp的第一个更改,因为它给出了每个更改所在的偏移量和行号,但如果你认为有更好的命令,我愿意接受:)谢谢

我想cmp -l file1 file2可能会做你想要的。从手册:

-l  --verbose
      Output byte numbers and values of all differing bytes.

输出是一个表,其中包含偏移量、file1中的字节值和file2中所有不同字节的值。它看起来像这样:

4531  66  63
4532  63  65
4533  64  67
4580  72  40
4581  40  55
[...]

所以第一个差异是在偏移量4531处,其中file1的十进制八进制字节值为66,而file2的

为63。

单个字节添加/删除的方法

diff <(od -An -tx1 -w1 -v file1) 
     <(od -An -tx1 -w1 -v file2)

生成一个删除64字节的测试用例:

for i in `seq 128`; do printf "%02x" "$i"; done | xxd -r -p > file1
for i in `seq 128`; do if [ "$i" -ne 64 ]; then printf "%02x" $i; fi; done | xxd -r -p > file2
输出:

64d63
<  40

如果您还想查看字符的ASCII版本:

bdiff() (
  f() (
    od -An -tx1c -w1 -v "$1" | paste -d '' - -
  )
  diff <(f "$1") <(f "$2")
)
bdiff file1 file2
输出:

64d63
<   40   @

在Ubuntu 16.04上测试。

我更喜欢od而不是xxd,因为:

  • 它是POSIX, xxd不是(自带Vim)
  • -An来删除没有awk的地址列。

命令的解释:

  • -An删除地址列。这一点很重要,否则在添加/删除字节后,所有行都将不同。
  • -w1每行放一个字节,以便diff可以使用它。每行有一个字节是至关重要的,否则删除后的每行将变得不一致和不同。不幸的是,这不是POSIX,而是GNU。
  • -tx1是您想要的表示,更改为任何可能的值,只要保持每行1字节。
  • -v防止星号重复缩写*可能干扰diff
  • paste -d '' - -每两行连接一次。我们需要它,因为十六进制和ASCII将进入单独的相邻行。取自:将每隔一行与下一行
  • 连接
  • 我们使用括号()来定义bdiff而不是{}来限制内部函数f的范围,参见:如何在Bash中定义函数内部的另一个函数?

参见:

  • https://superuser.com/questions/125376/how-do-i-compare-binary-files-in-linux
  • https://unix.stackexchange.com/questions/59849/diff-binary-files-of-different-sizes

我发现更有效的解决方法是使用od将二进制文件翻译成某种形式的文本。

那么任何口味的diff都可以。

最新更新