2011-04-12 20 views
13

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

思想: - 散列20个第一行中的文件1 - 散列中的文件2 20条第一线 - 比较两个散列,并且如果那些相等返回true。

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

+0

对不起,但这只是一个可怕的想法。不管你使用什么散列函数,产生冲突都是微不足道的。不妨将文件的前10个字符作为其“散列”。 – bdares 2011-04-12 08:52:27

+0

你对你将要比较的文件有什么了解?你可以做的第一件事就是使用文件大小作为散列的一部分。在文件系统中的成千上万(或成千上万个)文件中,两个文件具有相同的文件大小的比例非常非常低... – SyntaxT3rr0r 2011-04-12 09:16:23

回答

24

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

基于校验和或哈希的任何方法都容易发生冲突,但是您可以通过使用两种不同的RSYNC方法来最小化风险。

该算法基本上是:

  • 检查文件大小为等于
  • 打破文件到大小为N个字节的块
  • 计算校验和在每对匹配块的和比较。任何差异证明文件不一样。

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

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

如果是速度问题,只需使用Adler32,并且接受很少会检测不到差异。这真的很少见。像这样的校验和被用来确保互联网可以发现传输错误,并且你多久会得到错误的数据?

真的是所有关于精度,你将不得不比较每个字节。没有别的工作。

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

1

如果您在同一个系统上同时比较两个文件,则不需要对它们进行散列。只需比较两个文件中的字节数就可以了。如果你想在不同的时间比较它们,或者它们在不同的地方,那么MD5就会快速且充分。没有太多的理由需要更快的一个,除非你处理的是非常大的文件。即使我的笔记本电脑可以每秒散列数百兆字节。

如果你想验证它们是否相同,你还需要散列整个文件。否则,你可能只需检查大小和最后修改时间,如果你想真正快速检查。你也可以检查文件的开头和结尾,如果它们非常大,并且你相信中间不会改变。如果你不处理数百兆字节,你也可以检查每个文件的每个字节。

+0

我需要在不同的时间和时间比较这些文件所以我猜哈希是最好的选择。我正在考虑MD5,但想要做一些研究,如果有更快的。 感谢您的回答! – carloscloud 2011-04-12 09:05:20

+0

啊,好的。是的,MD5很可能会很好。如果你真的在处理大文件,那么这是[Java中的快速MD5实现](http://www.twmacinta.com/myjava/fast_md5.php)。 – WhiteFang34 2011-04-12 09:11:11