2009-04-16 73 views
6

1)爲了達到非常低的散列衝突的目的,我可以使用sha1的128位中的一半而不是處理sha1本身嗎?我知道這不適合加密哈希,但我只需要散列表密鑰的哈希值。確定只能使用64位的sha1哈希作爲ID?

2)計算時間不是一個優先事項,除此之外我正在散列非常小的數據。特別是,我主要將採取2或3個64位散列並散列它們以獲得另一個64位散列。爲此,有沒有比sha1更好的選擇?再一次碰撞應該不太可能。

3)我是一個SQL新手。在數據庫中使用64位散列作爲ID是否是個好主意?將64位ID導致sqlite或postgres的性能問題?我需要跨多個數據庫(包括Lucene索引)來協調數據,所以我想我應該直接在表中處理哈希值,而不是用自動遞增的ID(這隻會在一個數據庫中有意義,而不是跨所有數據存儲)。我認爲64位是一個很好的折衷:對於不太可能發生的衝突足夠大,但可以節省空間(和查找時間?)。

4)CRC-64怎麼樣?這是否會產生足夠的隨機分佈?

回答

6

如果你沒有足夠的記錄,幾乎可以確定你永遠不會有64位的散列衝突。可能你會屬於這個類別。

應該與修剪下來的加密哈希像SHA1沒有問題的,因爲如果在哈希是內部結構,那麼它是不夠好是一個加密散列,如果有那麼任何沒有結構這些比特的子集應該是非常隨機的。請注意,我只是在討論如何使用這些ID,而不是用於任何加密目的!

但是真的,你的SQL有沒有某種GUID?如果是這樣,爲什麼不使用它?

0

如果計算時間不重要,爲什麼不去整個128位?除了可能的存儲問題之外,是否有真正的理由選擇64位? (然後額外的8個字節是不會殺你的存儲這麼便宜)

64位與128位將導致SQLite沒有速度問題,我不確定mySQL。

+0

我認爲當使用隨機散列數據作爲關鍵字時,如果關鍵字適合機器原生整數而不是字符串,大多數數據庫系統對搜索和連接操作更有效。 – bhelm 2015-06-24 05:57:41

3

您的鑰匙將需要絕對獨特的不獨特性高的可能性。我建議使用GUID而不是使用散列作爲密鑰以實現跨數據庫兼容性。生成哈希作爲快速查找機制 - 你可以有一個非唯一索引 - 但在碰撞的情況下,你將不得不比較實際的數據,以確保它們是相同的。在同步數據庫時,您可以檢查散列(快速使用索引),如果發現衝突,則解析數據是否相同,因此需要解析GUID。如果沒有衝突,則只需更新哪個數據庫需要缺少的條目,然後使用其他數據庫中的GUID進行插入。

我也在創建自己的哈希散列以節省空間方面看點兒。如果你已經有了其他哈希值,只需使用它們(追加,不要重新哈希)。如果不是,只需使用標準散列函數(如MD5或SHA1)並存儲結果數據。

+1

但爲什麼我需要絕對唯一性?我們不是在談論很高的概率嗎? 1在2^128的機會,任何兩個項目都有相同的散列,對吧?我們可能不太擔心被流星擊中?或者MD5和sha1沒有足夠的隨機分配? – Jegschemesch 2009-04-16 04:09:49

+0

啊,我想我們正在說話,因爲我不知道GUID/UUID,而你似乎認爲我不是。但是,GUID並非絕對獨一無二,對吧? – Jegschemesch 2009-04-16 04:20:49

2

對於64位散列,您有1%的機會與6衝突。1×10 記錄。 (對於其他組合,請參閱Wikipedia的page on the Birthday problem。)您可以丟棄每個第二位的前64位或最後一位,這對散列的屬性沒有任何影響。