如何通过哈希比较文件的各个部分?

sin*_*ned 19 bash hashing

我有一个成功下载的文件和另一个失败的下载(只有大文件的前 100 MB),我怀疑它们是同一个文件。

为了验证这一点,我想检查它们的哈希值,但由于我只有未成功下载文件的一部分,因此我只想对前几兆字节进行哈希处理。

我该怎么做呢?

操作系统将是 Windows,但我安装了 cygwin 和 MinGW。

Kon*_*lph 56

如果您将一个文件与多个文件进行比较,或者将多个文件相互比较,则创建散列来比较文件是有意义的。

仅比较两个文件一次是没有意义的:计算散列的工作量至少与遍历文件并直接比较它们一样高。

一个有效的文件比较工具是cmp

cmp --bytes $((100 * 1024 * 1024)) file1 file2 && echo "File fragments are identical"
Run Code Online (Sandbox Code Playgroud)

您还可以将它与dd比较两个文件的任意部分(不一定是从头开始),例如:

cmp \
    <(dd if=file1 bs=100M count=1 skip=1 2>/dev/null) \
    <(dd if=file2 bs=100M count=1 skip=1 2>/dev/null) \
&& echo "File fragments are identical"
Run Code Online (Sandbox Code Playgroud)

  • `--bytes` 选项只会使任务复杂化。只需在没有此选项的情况下运行 `cmp`,它就会显示文件之间不同的第一个字节。如果所有字节都相同,那么它将在较短的文件上显示“EOF”。这将为您提供比示例更多的信息 - 多少字节是正确的。 (19认同)
  • 这是解决方案。如果你有 `bash` 运行,`cmp` 99.99% 肯定已经安装,它可以完成这项工作。事实上,`cmp -n 131072 one.zip two.zip` 也可以完成这项工作。输入的字符最少,执行速度最快。计算散列是无意义的。它需要读取整个 100MB 文件,_加上_完整文件的 100MB 部分,这是毫无意义的。如果它们是 zip 文件并且它们不同,则在前几百个字节内会有所不同。不过,预读默认提供 128k,因此您也可以比较 128k(与比较 1 个字节的成本相同)。 (8认同)
  • 注意:如果您想避免同时读取两个文件,创建哈希值来比较文件也是有意义的。 (6认同)
  • 如果你有 GNU `cmp`(我认为几乎每个人都有),你可以使用 `--ignore-initial` 和 `--bytes` 参数,而不是通过调用 `dd` 来使事情复杂化。 (2认同)

dav*_*ann 12

对不起,我不能完全尝试,但这种方法行得通

dd if=yourfile.zip of=first100mb1.dat bs=100M count=1
dd if=yourotherfile.zip of=first100mb2.dat bs=100M count=1
Run Code Online (Sandbox Code Playgroud)

这将为您提供两个文件的前 100 兆字节。

现在获取哈希值:

sha256sum first100mb1.dat && sha256sum first100mb2.dat 
Run Code Online (Sandbox Code Playgroud)

也可以直接运行:

dd if=yourfile.zip bs=100M count=1 | sha256sum 
dd if=yourotherfile.zip bs=100M count=1 | sha256sum 
Run Code Online (Sandbox Code Playgroud)

  • 为什么要创建哈希?这比直接比较文件片段(使用 `cmp`)效率低得多。 (8认同)

Ton*_*nny 7

每个人似乎都走 Unix/Linux 路线,但只需比较 2 个文件就可以使用 Windows 标准命令轻松完成:
FC /B file file2

FC 出现在有史以来的每个 Windows NT 版本中。并且(如果我没记错的话)也出现在 DOS 中。
它有点慢,但对于一次性使用来说并不重要。


Xen*_*050 6

您可以直接比较文件,使用二进制/十六进制差异程序,如vbindiff. 它可以快速比较 Linux 和 Windows 上高达 4GB 的文件。

看起来像这样,只有以红色突出显示的差异(1B 与 1C):

one                                       
0000 0000: 30 5C 72 A7 1B 6D FB FC  08 00 00 00 00 00 00 00  0\r..m.. ........  
0000 0010: 00 00 00 00                                       ....
0000 0020:
0000 0030:
0000 0040:
0000 0050:
0000 0060:
0000 0070:
0000 0080: 
0000 0090: 
0000 00A0: 

two        
0000 0000: 30 5C 72 A7 1C 6D FB FC  08 00 00 00 00 00 00 00  0\r..m.. ........  
0000 0010: 00 00 00 00                                       ....               
0000 0020: 
0000 0030:
0000 0040:
0000 0050:
0000 0060:
0000 0070:
0000 0080:
0000 0090:                                
0000 00A0:             
????????????????????????????????????????????????????????????????????????????????
?Arrow keys move  F find      RET next difference  ESC quit  T move top        ?
?C ASCII/EBCDIC   E edit file   G goto position      Q quit  B move bottom     ?
???????????????????????????????????????????????????????????????????????????????? 
Run Code Online (Sandbox Code Playgroud)

  • 如果您的意思是 ASCII 文本,那么这无关紧要。`vbindiff`(和 Konrad 的 `cmp`)逐字节比较二进制数据。实际上 has 值更容易发生碰撞 (2认同)