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

发布于 2024-12-20 02:10:56 字数 169 浏览 0 评论 0原文

我希望获得有关 Bash 脚本循环的一些帮助,该循环将显示两个二进制文件之间的所有差异,仅使用

cmp file1 file2 

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

I would love some help with a Bash script loop that will show all the differences between two binary files, using just

cmp file1 file2 

It only shows the first change I would like to use cmp because it gives a offset an a line number of where each change is but if you think there's a better command I'm open to it :) thanks

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

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

发布评论

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

评论(3

清秋悲枫 2024-12-27 02:10:56

我认为 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 的 decimal 八进制字节值为 66,file2 的值为 63。

I think cmp -l file1 file2 might do what you want. From the manpage:

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

The output is a table of the offset, the byte value in file1 and the value in file2 for all differing bytes. It looks like this:

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

So the first difference is at offset 4531, where file1's decimal octal byte value is 66 and file2's is 63.

我们的影子 2024-12-27 02:10:56

适用于单字节添加/删除的方法

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 因为:

  • 是 POSIXxxd 不是(Vim 自带)
  • -An 来删除地址列而不awk。

命令解释:

  • -An 删除地址栏。这很重要,否则在添加/删除字节后所有行都会有所不同。
  • -w1 每行放置一个字节,以便 diff 可以使用它。每行一个字节至关重要,否则删除后的每一行都会变得不同步并且不同。不幸的是,这不是 POSIX,而是 GNU 中的。
  • -tx1 是你想要的表示形式,可以更改为任何可能的值,只要每行保留 1 个字节即可。
  • -v 防止星号重复缩写 *,这可能会干扰 diff
  • paste -d '' - - 每两行连接。我们需要它,因为十六进制和 ASCII 进入不同的相邻行。摘自:将所有其他行与下一行连接
  • 我们使用括号< code>() 定义 bdiff 而不是 {} 来限制内部函数 f 的范围,另请参阅:<一个href="https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash">如何在 Bash 中的另一个函数中定义一个函数?

另请参阅:

Method that works for single byte addition/deletion

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

Generate a test case with a single removal of byte 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

Output:

64d63
<  40

If you also want to see the ASCII version of the character:

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

bdiff file1 file2

Output:

64d63
<   40   @

Tested on Ubuntu 16.04.

I prefer od over xxd because:

  • it is POSIX, xxd is not (comes with Vim)
  • has the -An to remove the address column without awk.

Command explanation:

  • -An removes the address column. This is important otherwise all lines would differ after a byte addition / removal.
  • -w1 puts one byte per line, so that diff can consume it. It is crucial to have one byte per line, or else every line after a deletion would become out of phase and differ. Unfortunately, this is not POSIX, but present in GNU.
  • -tx1 is the representation you want, change to any possible value, as long as you keep 1 byte per line.
  • -v prevents asterisk repetition abbreviation * which might interfere with the diff
  • paste -d '' - - joins every two lines. We need it because the hex and ASCII go into separate adjacent lines. Taken from: Concatenating every other line with the next
  • we use parenthesis () to define bdiff instead of {} to limit the scope of the inner function f, see also: How to define a function inside another function in Bash?

See also:

勿挽旧人 2024-12-27 02:10:56

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

那么任何 diff 风格都可以正常工作。

The more efficient workaround I've found is to translate binary files to some form of text using od.

Then any flavour of diff works fine.

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