如果散列算法受 CPU 限制,那么如何检查大文件身份?

如果散列算法受 CPU 限制,那么如何检查大文件身份?

对于小文件,散列还行,但对于大文件,你很容易发现md5sum它对 CPU 有限制。有没有可以在多个核心上扩展的散列算法?有什么解决方法吗?有什么想法吗?有什么吗?:)

答案1

我自己目前最好的解决方案是:

parallel --block=512M --pipepart -a …HUGEFILE… --progress --recend '' \ -k -j …NUMofProcessesSay4… md5sum | md5sum

- 应当指出的是:

  1. 生成的 md5 哈希值不是文件的哈希值,而是文件的各部分的 md5 哈希值,但它仍允许您比较副本是否与原件相同
  2. 它的性能也不是很好,特别是当你使用pipe而不是文件作为输入时
  3. parallel--pipepart我发现它不支持磁盘分区

因此我也想听听其他解决方法。

答案2

不幸的是,MD5 是一个线性过程,其状态取决于所有先前的输入。换句话说,您无法真正并行化它。此外,我不知道有任何真正的哈希算法不以这种方式运行。

您可以做的(并且根据您的回答,您正在做的)是拆分源文件并同时计算每个块的 md5sum。

如果你不能/不想这样做,你必须使用更快的哈希函数哈希城市哈希或者幽灵哈希

其他想法(也许它适用于您的预期用途):如果您需要比 MD5 更快的东西(尽管是单线程的),您可以使用 CRC32(由最近的 CPU 硬件加速)进行第一次快速传递,然后使用 MD5/SHA1 对看似相同的文件进行第二次传递。

答案3

几乎没有办法绕过处理整个文件。MD4 或 CRC32 可能是广泛部署且快速的算法的最佳选择(尽管 CRC32 的效率远低于 MD4)。

测试所选算法的各种实现会有所帮助。如果您能找到经过良好测试的 asm 实现,它可能会提高其 C/C++ 同类算法的性能。

如果您真的不关心互操作性,那么跨多个核心进行哈希处理很容易,只需将文件拆分成块(不需要在磁盘上完成,您只需从特定偏移量开始读取)并分别处理每个块(但这会导致严重的磁盘抖动,从而降低性能,尤其是对于机械磁盘)。您最终会得到每个块的单独哈希值(尽管这还有其他优点,例如指向损坏的块),但您始终可以将它们哈希在一起以获得一个最终值。

Gist 可能是 Python 中某些内容的一个良好开端。

答案4

我正在开发一个树形哈希项目,它就是为解决这一问题而设计的:现成的大型文件并行哈希。它现在可以工作,尽管尚未经过审核,并且审核中的更改很可能会导致最终摘要的更改。话虽如此,它非常快:https://github.com/oconnor663/bao

相关内容