2012-07-22 100 views
3

我使用adler32校驗和算法從數據庫ID生成一個數字。所以,當我將一行插入到數據庫中時,我採用該行的標識並使用它來創建校驗和。我遇到的問題是我僅在207次插入數據庫後生成了重複校驗和。這比我預期的要快得多。這裏是我的代碼:Adler32快速重複

String dbIdStr = Long.toString(dbId); 
byte[] bytes = dbIdStr.getBytes(); 
Checksum checksum = new Adler32(); 
checksum.update(bytes, 0, bytes.length); 
result = checksum.getValue(); 

我在做什麼/我怎麼做有什麼問題?我應該使用不同的方法來創建獨特的字符串嗎?我這樣做是因爲我不想在一個url中使用數據庫ID ......改變數據庫的結構將打破世界上所有的鏈接。

謝謝!

+0

您的代碼目前看起來是正確的。也許你的「結果」是一個「字節」而不是「長」?或者「dbId」並不像你想象的那麼獨特... 其實,我根本不理解你的問題。您需要一個唯一的ID來標識數據庫。並且你的每個數據庫已經*有一個名爲「dbId」的唯一標識符,但是你不想使用它,因爲「???」。所以相反,你需要*非常相同的dbId *並將其轉換爲字符串,並使用Adler32對其進行哈希處理,然後使用* that *作爲「唯一」ID。但是這個散列仍然基於你不想使用的dbId! – Quuxplusone 2012-07-22 04:49:10

+0

比方說,我給你一個鏈接到我的系統中的帖子:example.com/posts/1。然後讓我們說我需要重新組合我的數據庫中的東西(或者完全轉移到另一種類型的存儲),這會導致數據庫標識更改。現在你有一個斷開的鏈接。這就是我產生這些哈希的原因。此外,我剛剛檢查了一些在線哈希工具,似乎在我的系統(126和207)上發生碰撞的兩個id確實爲這些工具產生了相同的adler32結果。例如:http://www.fileformat.info/tool/hash.htm – threejeez 2012-07-22 05:00:05

+0

只是爲了增加我的推理,似乎許多熱門網站都做同​​樣的事情。例如:http://pinterest.com/pin/186758715768172705/。我懷疑他們的網站有超過186個quadrillion的帖子! – threejeez 2012-07-22 05:03:24

回答

9

你應該不是使用Adler-32作爲哈希碼生成器。這不是它的目的。您應該使用具有良好散列屬性的算法,其中最大限度地減少了衝突的概率。

您可以簡單地使用Java的hashCode方法(在任何對象上)。對於字符串對象,哈希碼是字符串乘以31的連續冪的字節值的總和。可能會碰到很短的字符串,但這不是一個可怕的算法。作爲散列算法,它肯定比Adler-32好很多。

無論是在執行時間還是哈希碼大小方面,使用加密安全散列函數(如SHA-256)的建議對您的應用程序來說肯定是過分的。您應該嘗試使用Java的hashCode並查看您獲得的碰撞數量。如果它看起來比你期望的頻率要高得多,那麼你可以用一個更好的覆蓋它來覆蓋它。如果它看起來比你期望的更頻繁(其中n是散列碼中的比特數)你可以找到一個鏈接here for decent Java hash functions

+0

感謝您的提示,但是我使用Java和CityHash是C++。 – threejeez 2012-07-22 07:40:26

+3

@Miles:這不僅僅是一個提示,他似乎是發明了校驗和的*阿德勒。 – 2012-07-22 14:48:31

+0

@GregS,但我會通過'hashCode'選擇SHA-256。 'hashCode'也是32位,衝突完全依賴於某個類的實現。如果它實際上比Adler32更好,我會感到驚訝 - 「hashCode」的許多天真實現當然是這方面的一個缺點。 – 2012-07-22 15:10:24

0

嘗試使用像SHA-256這樣的安全散列函數。如果您發現任何數據不是二進制平等的衝突,您的銀行賬戶將獲得1000美元的獎勵。如果/當SHA-2被破解並且您故意進入衝突時,優惠結束。也就是說,輸出是32位而不是32位。

+0

不幸的是,SHA-256產生的字符串對於url來說太長了(在用戶友好方面)。我需要一些更短,最好是所有數字。 – threejeez 2012-07-23 00:06:36

+0

好的,但是對於32位和大型數據庫,由於生日悖論,您可能會遇到大約2^16個元素的碰撞,這就是您使用完美哈希算法的原因。那大概是64Ki的ID。當然,如果你不走運,或者你使用的是次優散列(但你已經跑到最後一個我猜到的),你可能會碰到更多的碰撞。 – 2012-07-23 00:26:34