检查两个文件是否相等的最快哈希算法是什么?

efl*_*les 58 hash file crc

创建哈希函数的最快方法是什么,用于检查两个文件是否相等?

安全性不是很重要.

编辑:我通过网络连接发送文件,并确保双方的文件相同

Aar*_*lla 47

除非您使用非常复杂和/或慢速的哈希,否则从磁盘加载数据所需的时间比计算哈希值要长得多(除非您使用RAM磁盘或高端SSD).

因此,要比较两个文件,请使用此算法:

  • 比较大小
  • 比较日期(这里要小心:这可能会给你错误的答案;你必须测试是否适合你)
  • 比较哈希

这允许快速失败(如果大小不同,您知道文件不同).

为了使事情更快,您可以计算一次哈希并将其与文件一起保存.还要将文件日期和大小保存到这个额外的文件中,这样您就可以快速了解何时必须重新计算哈希值或在主文件更改时删除哈希文件.

  • 我已经实现了一个工作解决方案,它使用NTFS下的备用数据流来存储哈希值.然而,我必须要做的一件事是给哈希加时间戳,以便我可以判断文件是否已被修改,因为它最后被哈希过. (4认同)
  • 今天的快速磁盘读取速度为每秒2.5GB.根据我的经验,哈希远没有那么快. (2认同)

Gre*_*ill 25

一种方法可能是使用简单的CRC-32算法,并且仅当CRC值比较相等时,使用SHA1或更强大的东西重新运行散列.快速CRC-32将在任何一天都优于加密安全散列.

  • 我将在这里自相矛盾:如果只有两个长度相等的文件,你不会通过哈希比直接比较更快.如果您有许多文件并且想要找到相等的候选者,则哈希是有意义的. (23认同)
  • 我会说散列文件可能无论如何都是I/O绑定,所以你不妨使用具有良好分布和大范围的散列(当然任何加密散列都有资格). (11认同)
  • 如果您通过网络比较文件(如OP所示),则读取每个文件相当于再次通过网络重新传输文件.所以使用某种散列可能是有道理的.但我同意第一次使用一个好的哈希算法,而不是做一个初步的CRC32,然后是其他东西. (7认同)
  • 即使只是在本地比较,如果所需的唯一结果是“等于”/“不等于”,则散列可能仍然有意义,因为这允许驱动器/操作系统尽可能快地读取文件,而不是在之间交替块2 个文件。 (3认同)
  • @StevenSudit它不是快速SSD上的IO绑定.我有一个测试文件,md5需要一分钟,但我的SSD可以在25秒内读取文件.我的SSD已有几年历史了,你现在可以获得更快的速度. (2认同)

rog*_*ack 20

xxhash声称自己非常快速和强大,碰撞明智:

http://cyan4973.github.io/xxHash/

有一个64位变体在64位处理器上运行"甚至更快"而不是32位整体,但在32位处理器上运行速度较慢(如图所示).

http://code.google.com/p/crcutil也说是相当快的(并充分利用硬件CRC指令,其中存在,这可能是非常快的,但是如果你没有支持他们的硬件,不一样快).不知道CRC32c是否与xxHash一样好(就碰撞而言)...

https://code.google.com/p/cityhash/似乎与crcutil类似,并且[如果指示它可以编译为使用硬件CRC32c指令].

如果你"只想要最快的原始速度"并且不关心散列输出的随机分布质量(例如,使用小集合,或速度是最重要的),这里提到了一些快速算法:http ://www.sanmayce.com/Fastest_Hash/(在某些情况下,这些"不太随机"的分布式算法"足够好"并且速度非常快).显然FNV1A_Jesteress是"长"字符串最快,有些可能是小字符串. http://locklessinc.com/articles/fast_hash/似乎也很相关.我没有研究看这些碰撞特性是什么.

  • “总体而言,有一个 64 位变体在 64 位处理器上运行速度比 32 位处理器“更快”,但在 32 位处理器上运行速度较慢(见图)。” - 好吧,我认为 64 位代码针对 64 位处理器进行了优化,并且使用 64 位长整数对哈希机制进行分块。 (2认同)

int*_*nt3 5

您可以尝试MurmurHash,它经过专门设计,速度很快,并且编码非常简单。如果 MurmurHash 返回匹配项,您可能需要第二个更安全的哈希值,只是为了确定。

  • OP 表示这里不考虑安全性,所以我不确定为什么第二个哈希会有所帮助。相反,我建议使用 Murmur 的 64 位变体之一。 (2认同)

小智 5

我们在这里优化的是花在任务上的时间。不幸的是,我们对手头的任务了解不够,无法知道最佳解决方案应该是什么。

是为了一次性比较2个任意文件吗?然后比较大小,然后简单地逐字节(或逐 mb)比较文件(如果这对您的 IO 更好)。

如果是2个大的文件组,或者很多组文件,这不是一次性的练习。但如果是经常发生的事情,那么应该为每个文件存储哈希值。哈希值从来都不是唯一的,但是具有 9 个数字(32 位)的哈希值可以用于大约 40 亿个组合,而 64 位数字足以区分一些 16 * 10^18 Quintillion 的不同文件。

一个不错的折衷方案是为每个文件生成 2 个 32 位哈希值,一个用于前 8k,另一个用于 1MB+8k,将它们组合在一起作为单个 64 位数字。将所有现有文件编入数据库应该相当快,并且根据该数据库查找候选文件也应该非常快。一旦出现匹配,确定它们是否相同的唯一方法就是比较整个文件。

我坚信应该为人们提供他们需要的东西,但这并不总是他们认为自己需要的东西,或者他们想要的东西。