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

时间:2011-04-12 08:48:37

标签: java performance comparison hash-function

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

思想: - 散列文件1中的20个第一行 - 散列文件2中的20个第一行 - 比较两个哈希值,如果相等则返回true。

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

2 个答案:

答案 0 :(得分:27)

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

任何基于校验和或散列的方法都容易受到冲突的影响,但您可以通过RSYNC的方式使用两种不同的方法来最小化风险。

该算法基本上是:

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

这允许早期检测差异。您可以通过使用不同的算法或不同的块大小一次计算两个校验和来改进它。

结果中的更多位表示发生冲突的可能性更小,但是一旦超过64位,就会超出Java(和计算机的CPU)可以原生处理的速度,因此速度变慢,因此FNV-1024不太可能给你一个假阴性,但速度要慢得多。

如果完全是关于速度,只需使用Adler32并接受很少会检测到差异。这真的很罕见。这些校验和用于确保互联网可以发现传输错误,以及您多久出现错误的数据?

真的是关于准确性,你必须比较每个字节。没有别的办法。

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

答案 1 :(得分:2)

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

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