如何比较二进制文件以检查它们是否相同?


186

知道两个二进制文件是否相同(时间戳除外)的最简单方法(在Ubuntu Linux上使用图形工具或命令行)是什么?我不需要实际提取差异。我只需要知道它们是否相同即可。


5
一个问题问到表演如何:它们之间的区别superuser.com/questions/125376/...
西罗桑蒂利郝海东冠状病六四事件法轮功

2
的手册页cmp专门说它进行逐字节比较,因此这是我默认的2个二进制文件。diff是逐行的,将为您提供相同的是/否答案,但当然不是相同的转储到标准输出流。如果行很长,因为它们可能不是文本文件,那么我会更喜欢cmpdiff具有的优点是您可以指定目录和-rfor 的比较,以进行递归,从而在一个命令中比较多个文件。
H2ONaCl

Answers:


180

标准的Unix diff将显示文件是否相同:

[me@host ~]$ diff 1.bin 2.bin
Binary files 1.bin and 2.bin differ

如果命令没有输出,则表示文件没有差异。


5
diff似乎对大型文件有问题。diff: memory exhausted比较两个13G文件时得到一个。
吴永伟

1
有趣的输出。diff告诉您它们是“二进制” fies。由于所有文件都可以视为二进制文件,因此这是一个奇怪的断言。
H2ONaCl

6
您可以使用以下选项报告相同的文件:diff -s 1.bin 2.bindiff --report-identical-files 1.bin 2.bin这显示Files 1.bin and 2.bin are identical
Tom Kuschel

1
不,它将说它们是“不同的”,所以它们并不相同
Josef Klimuk

1
我有两个可执行文件,我知道它们是不同的,因为我编译并运行了它们,但是这里给出的diff和cmp的所有选项都将它们判断为相同。为什么?!!!
mirkastath19年

107

使用cmp命令。如果它们是二进制相等的,它将干净地退出,或者将打印出出现第一个差异的位置并退出。


9
对于用例,OP描述IMHO cmp的效率更高diff。所以我更喜欢这个。
halloleo

5
我有一个运行的shell脚本:cmp $1 $2 && echo "identical" || echo "different"
steveha 2014年

2
找到第一个差异并显示它或贯穿文件结尾时,cmp会停止吗?
SOP

cmp具有“静音”模式:-s, --quiet, --silent- suppress all normal output。我尚未测试,但我认为如果有第一个差异,它将停止。
维克多·亚雷玛

89

我发现Visual Binary Diff是我要找的东西,可在以下位置找到:

  • Ubuntu:

    sudo apt install vbindiff
    
  • Arch Linux:

    sudo pacman -S vbindiff
    
  • 通过MacPorts的 Mac OS X :

    port install vbindiff
    
  • 通过Homebrew的Mac OS X:

    brew install vbindiff
    

1
很好...我/想/我只想知道文件是否有所不同。但是能够轻松看到确切的差异要有用得多。当我到达文件末尾时,它倾向于出现段错误,但是没关系,它仍然有效。
杰里米(Jeremy)2016年

2
有人说过几次,但这是一个很棒的小程序!(fyi也使用自制软件)
johncip '17

2
这应该是公认的答案,因为它比规范的diff命令的平淡无益的输出方法优越得多。
Gearoid Murphy '18

1
这是二进制比较的最佳工具。
卡拉·卡玛戈

17

使用sha1生成校验和:

sha1 [FILENAME1]
sha1 [FILENAME2]

3
如果只有一个文件的校验和,这将很有用,但是如果两个文件都在磁盘上,则没有必要。diffcmp会不费吹灰之力就告诉您它们是否不同。
johncip '17

1
是不是sha1sum不是sha1
kol

2
NetBSD上的sha1,Linux上的sha1sum
Scott Presnell

2
有两个文件尽管是不同的,这将返回相同的结果:shattered.io
MIK

2
SHA1已经发生了一次公共碰撞(shattered.io),也可能有一些非公开碰撞。一次冲突可用于生成无数个冲突文件,请改用SHA2进行哈希处理。
Michal Ambroz

12

我最终使用hexdump将二进制文件转换为十六进制表示形式,然后在meld / kompare /其他任何diff工具中打开它们。与您不同,我追求文件中的差异。

hexdump tmp/Circle_24.png > tmp/hex1.txt
hexdump /tmp/Circle_24.png > tmp/hex2.txt

meld tmp/hex1.txt tmp/hex2.txt

1
hexdump -v -e '/1 "%02x\n"'如果要比较并确切地看到插入或删除了哪些字节,请使用。
William Entriken '17

当二进制文件不首先转换为十六进制时,Meld也可以使用它们。它显示不在char集中的内容的十六进制值,否则显示普通chars,这对于还包含一些ascii文本的二进制文件很有用。许多这样做,至少是从魔术弦开始的。
Felix Dombek

7

您可以使用MD5哈希函数来检查两个文件是否相同,这样就不能从低层次看到差异,但是这是比较两个文件的快速方法。

md5 <filename1>
md5 <filename2>

如果两个MD5哈希(命令输出)相同,则两个文件没有不同。


7
你能解释一下你的反对票吗?SHA1有4个投票,并且如果OP认为两个文件可能相同或相似,则发生冲突的可能性很小,不值得MD5向下投票,而SHA1则无需投票,因为您听说过应该散列您的SHA1而不是MD5输入密码(这是另一个问题)。
瑞奇(Rikki)

2
不知道的原因,但一个纯粹的CMP会比计算文件的任何散列函数,并比较它们(至少在只有2个文件)更有效
帕维尔Szczur

1
如果两个文件很大且在同一磁盘上(而不是ssd),则md5或sha *变体可能会更快,因为磁盘可以顺序读取两个文件,从而节省了很多磁头运动
Daniel Alder

7
我之所以投票,是因为您发布了一个较早(较差)解决方案的较小变体,而该评论本来应该是一个评论。
johncip '17

6

使用cmp命令。有关更多信息,请参考二进制文件和强制文本比较

cmp -b file1 file2

1
-b不以“二进制模式”比较文件。它实际上是“使用GNU cmp,您还可以使用-bor --print-bytes选项显示这些字节的ASCII表示形式。”。这正是我使用您提供的手册中的URL找到的。
维克多·亚雷玛

Victor Yarema,我不知道您所说的“二进制模式”是什么意思。cmp在我看来,本质上是二进制比较。该-b选项仅打印不同的第一个字节。
H2ONaCl

4

为了查找闪存缺陷,我必须编写此脚本来显示所有包含差异的1K块(不仅是第一个cmp -b

#!/bin/sh

f1=testinput.dat
f2=testoutput.dat

size=$(stat -c%s $f1)
i=0
while [ $i -lt $size ]; do
  if ! r="`cmp -n 1024 -i $i -b $f1 $f2`"; then
    printf "%8x: %s\n" $i "$r"
  fi
  i=$(expr $i + 1024)
done

输出:

   2d400: testinput.dat testoutput.dat differ: byte 3, line 1 is 200 M-^@ 240 M- 
   2dc00: testinput.dat testoutput.dat differ: byte 8, line 1 is 327 M-W 127 W
   4d000: testinput.dat testoutput.dat differ: byte 37, line 1 is 270 M-8 260 M-0
   4d400: testinput.dat testoutput.dat differ: byte 19, line 1 is  46 &  44 $

免责声明:我在5分钟内入侵了脚本。它不支持命令行参数,也不支持文件名中的空格


我收到“ r:not found”(使用GNU linux)
unseen_rider

@unseen_rider哪个外壳,哪个行?使用请拨打脚本sh -x调试
丹尼尔·阿尔德

这是通过从终端调用脚本来完成的。线为9
unseen_rider

@unseen_rider我不能这样帮你。脚本还可以。请将您的调试输出发布到pastebin.com。您可以在这里看到我的意思:pastebin.com/8trgyF4A。另外,请告诉我readlink -f $(which sh)
Daniel Alder

最后一条命令给出/bin/dash。当前在pastebin上创建粘贴。
unseen_rider

4

带有以下选项的Diff会进行二进制比较,以检查文件是否完全不同,并输出文件是否相同:

diff -qs {file1} {file2}

如果要比较两个目录中具有相同名称的两个文件,则可以使用以下格式:

diff -qs {file1} --to-file={dir2}

OS X El Capitan


3

尝试diff -s

简短的答案:diff-s开关运行。

长答案:请在下面阅读。


这是一个例子。首先创建两个具有随机二进制内容的文件:

$ dd if=/dev/random bs=1k count=1 of=test1.bin
1+0 records in
1+0 records out
1024 bytes (1,0 kB, 1,0 KiB) copied, 0,0100332 s, 102 kB/s

                                                                                  
$ dd if=/dev/random bs=1k count=1 of=test2.bin
1+0 records in
1+0 records out
1024 bytes (1,0 kB, 1,0 KiB) copied, 0,0102889 s, 99,5 kB/s

现在,让我们复制第一个文件:

$ cp test1.bin copyoftest1.bin

现在,test1.bin和test2.bin应该不同:

$ diff test1.bin test2.bin
Binary files test1.bin and test2.bin differ

...以及test1.bin和copyoftest1.bin应该相同:

$ diff test1.bin copyoftest1.bin

可是等等!为什么没有输出?!

答案是:这是设计使然。相同文件上没有输出。

但是有不同的错误代码:

$ diff test1.bin test2.bin
Binary files test1.bin and test2.bin differ

$ echo $?
1


$ diff test1.bin copyoftest1.bin

$ echo $?
0

现在幸运的是,您不必每次都检查错误代码,因为您可以使用-s(或--report-identical-files)开关使diff更冗长:

$ diff -s test1.bin copyoftest1.bin
Files test1.bin and copyoftest1.bin are identical

2

Radiff2是一种用于比较二进制文件的工具,类似于常规diff比较文本文件的方式。

尝试radiff2将其作为radare2反汇编程序的一部分。例如,使用以下命令:

radiff2 -x file1.bin file2.bin

您会获得格式精美的两列输出,其中突出显示了差异。


1

我最喜欢的使用vim包中的xxd hex-dumper:

1)使用vimdiff(vim的一部分)

#!/bin/bash
FILE1="$1"
FILE2="$2"
vimdiff <( xxd "$FILE1" ) <( xxd "$FILE2" )

2)使用差异

#!/bin/bash
FILE1=$1
FILE2=$2
diff -W 140 -y <( xxd $FILE1 ) <( xxd $FILE2 ) | colordiff | less -R -p '  \|  '

0
md5sum binary1 binary2

如果md5sum相同,则二进制文件相同

例如

md5sum new*
89c60189c3fa7ab5c96ae121ec43bd4a  new.txt
89c60189c3fa7ab5c96ae121ec43bd4a  new1.txt
root@TinyDistro:~# cat new*
aa55 aa55 0000 8010 7738
aa55 aa55 0000 8010 7738


root@TinyDistro:~# cat new*
aa55 aa55 000 8010 7738
aa55 aa55 0000 8010 7738
root@TinyDistro:~# md5sum new*
4a7f86919d4ac00c6206e11fca462c6f  new.txt
89c60189c3fa7ab5c96ae121ec43bd4a  new1.txt

1
不完全的。只有可能性很高。
sawa

失败的概率是多少?
ashish

苗条,但比使用的某种变体更糟diff,没有理由不喜欢它。
sawa

为了使该建议切实可行,您必须将MD5哈希更改为SHA2。现在,任何人的笔记本电脑都可以在MD5中生成冲突,并基于此单个冲突前缀(两个相同大小,相同前缀和相同MD5的文件)生成无限数量的冲突文件(具有相同的前缀,不同的冲突块,相同的后缀)
Michal Ambroz

-1

有一种相对简单的方法来检查两个二进制文件是否相同。

如果以编程语言使用文件输入/输出;您可以将两个二进制文件的每一位存储到它们自己的数组中。

此时检查很简单:

if(file1 != file2){
    //do this
}else{
    /do that
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.