在Java中实现的“最快”哈希函数,比较文件的一部分

我需要比较Java中实例“File”的两个不同文件,并希望使用快速哈希函数来执行此操作。

想法: - 对文件 1 中的 20 个前行进行哈希处理 - 对文件 2 中的前 20 行进行哈希处理 - 比较两个哈希值,如果它们相等,则返回 true。

我想使用在Java中实现的“最快”哈希函数。你会选择哪一个?


答案 1

如果你想要速度,不要散列!特别是不像MD5这样的加密哈希。这些哈希值被设计为无法逆转,计算速度不快。您应该使用的是校验和 - 请参阅及其两个具体实现。Adler32的计算速度非常快。java.util.zip.Checksum

任何基于校验和或哈希的方法都容易受到冲突的影响,但您可以通过以 RSYNC 的方式使用两种不同的方法来最大限度地降低风险。

算法基本上是:

  • 检查文件大小是否相等
  • 将文件分解为大小为 N 字节的块
  • 计算每对匹配块的校验和并进行比较。任何差异都证明文件不相同。

这样可以及早发现差异。您可以通过使用不同的算法或不同的块大小同时计算两个校验和来改进它。

结果中的位越多意味着碰撞的可能性越小,但是一旦你超过64位,你就超出了Java(和计算机的CPU)可以本地处理的范围,因此速度变慢,所以FNV-1024不太可能给你一个假阴性,但速度要慢得多。

如果一切都与速度有关,只需使用Adler32并接受很少会检测到差异的事实。这真的是罕见的。像这样的校验和用于确保互联网可以发现传输错误,你多久出现一次错误的数据?

这完全是关于准确性的,你必须比较每个字节。其他一切都行不通。

如果您可以在速度和准确性之间做出折衷,那么有很多选择。


答案 2

如果您在同一系统上同时比较两个文件,则无需对它们进行哈希处理。只需比较两个文件中的字节是否相等,因为您读取两个文件。如果您希望在不同的时间比较它们,或者它们在不同的地方,那么MD5将既快速又充足。没有太多理由需要一个更快的文件,除非你正在处理非常大的文件。甚至我的笔记本电脑也可以每秒散列数百兆字节。

如果要验证它们是否相同,还需要对整个文件进行哈希处理。否则,如果您想进行快速检查,不妨检查大小和上次修改时间。您还可以检查文件的开头和结尾,如果它们真的很大,并且您相信中间不会改变。如果您不处理数百兆字节,则不妨检查每个文件的每个字节。


推荐