2015-10-02 53 views
2

我已經有一個64位散列函數庫(C編碼),但我只需要48位。我需要將64位散列值修剪爲48位值,但它必須以安全的方式來減少衝突。如何將64位散列值縮短爲48位值?

散列函數是一個很好的64位散列函數。它已經通過SMHasher(「DieHarder」哈希測試)進行了測試,並且證明比Murmur2更好。據我的同事們說,在lib中執行64位哈希的算法是xxHash,使用SMHasher進行了測試,得到了10的Q.Score!對於那些想看到它的人,可以在github.com上找到xxHash的源代碼:github.com/Cyan4973/xxHash/releases/latest

其基本思想是讓64位散列值(或其中的一部分)中的所有位對生成的48位散列值產生影響。有沒有辦法做到這一點?

[後期編輯]:
所以我已經實現了我自己的48位(準)-UUID發電機。
請在此檢查完整的工作解決方案(包括源代碼):https://stackoverflow.com/a/47895889/4731718

+10

如果它真的是一個很好的64位散列函數,那麼它基本上是隨機位,所以你可以以任何你喜歡的方式獲取48個散列函數。 –

+0

沒有信息保存在散列碼中,除非你特別使用一些特殊的信息,比如本地敏感散列。總之,你只需選擇最低的48位,就是這樣吧 – HuStmpHrrr

+0

即使它是一個非常好的散列函數,無論你做什麼,你都會失去16位的碰撞安全性。如果你不知道內部結構,你甚至可能會失去超過預期的四分之一的碰撞安全性。 – SkryptX

回答

10

如果64位散列是好的,那麼選擇任何48位也將是一個很好的散列。 @Lee Daniel。當然,信息丟失,不可逆。

unsigned long long Mask48 = 0xFFFFFFFFFFFFu; 
unsigned long long hash48 = hash64 & Mask48; 

如果64位散列函數很弱,那麼mod由pow(2,48)下的最大的素數。有些水桶會丟失。這不會損害一個好的散列,但肯定會使散列更好。

unsigned long long LargestPrime48 = 281474976710597u; // FFFFFFFFFFC5 
unsigned long long hash48 = hash64 % LargestPrime48; 
+2

最後,掌握數學的人...... :) –

2
hash >>= 16; 

但是,如果你感覺更好任意保留另外16位只是使用XOR。

hash = (hash >> 16)^(hash & 0xFFFF); 
+1

謝謝,我正在考慮類似的東西/相同的東西......但仍然需要看到也許有人會帶來一些好主意。有人擁有強大的數學技能也許:) –

3

據我所知,目前還沒有48位散列算法。無論是48位變量類型都不存在,所以無論如何這是一個非常奇怪的設計選擇。

當然,您無法將64位散列值縮短到48位而不會丟失,而安全散列值無論如何都是完全不同的主題。你可以做一些像使用CRC32這樣的常用32位散列函數,只需要16個空位。或者甚至結合32位和16位,但看起來真的很奇怪。從碰撞安全的角度來看,這甚至不是一件事情,我也不想聽到密碼學經驗豐富的人對此的反應。

我的推薦:使用標準大小的已建立哈希算法,不做實驗。無論如何,已經很難提出一個好的散列算法。除了你是你的領域的專家並且能夠處理變化可能產生的影響(這可能是最困難的部分),沒有必要變得富有創造力。

+2

誰告訴你一個48位變量類型不存在?有許多編譯器具有原生24/40/48位類型,如[TI或Motorola DSP5600x/3xx系列編譯器](https://stackoverflow.com/q/17834838/995714)。甚至可以在64位體系結構上實現48位變量 –

+1

我發現48位散列算法確實存在,例如,您可以在互聯網上搜索「_Bobcat 48位散列_」。 –