2011-04-12 19 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