djb2:一個產生簡單的隨機分布的哈希函數
目錄
- LCG算法
- 示例代碼
- djb2
- 示例代碼
- 為什麽選擇參數33和
- 33 was chosen because:
- 5381 was chosen because
- 哈希選擇參考
LCG算法
djb2與LCG很類似,故先介紹 LCG。
LCG(linear congruential generator)算法是一個古老的產生隨機數的算法。由以下參數產生
參數 | m | a | c | X |
---|---|---|---|---|
性質 | 模數 | 乘數 | 加數 | 隨機數 |
作用 | 取模 | 移位 | 偏移 | 作為結果 |
LCG算法是如下的一個遞推公式,每下一個隨機數是當前隨機數向左移動 log2 a 位,加上一個 c,最後對 m 取余,使隨機數限制在 0 ~ m-1 內
從該式可以看出,該算法由於構成簡單,具有以下優點:
- 計算速度快
- 易於實現
- 易於寫入硬件
以下是針對不同參數 lcg 產生隨機數的效果圖
可以看出,針對不同的參數,lcg產生的效果差別很大
以下是針對不同環境下的參數選擇
詳見wiki
示例代碼
def lcg(modulus, a, c, seed):
while True:
seed = (a * seed + c) % modulus
yield seed
djb2
djb2是一個產生隨機分布的的哈希函數,與LCG的算法相似。
以下是 djb2 的哈希函數:
X = (a * X) + c; // "mod M", M = 2^32 或 2^64
示例代碼
// generates a hash value for a sting
// same as djb2 hash function
//構造哈希函數 f(hash)= hash * 33 + c
unsigned int CountMinSketch::hashstr(const char *str) {
unsigned long hash = 5381;
int c;
while (c = *str++) {
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash;
}
本部分利用djb2處理字符串。
其中參數常有以下取值:
M=2^32
M常取一個較大的質數,以減少沖突。
由於哈希函數構造簡單,使用移位和相加的操作,所以計算速度快。
要註意hash值的計算,在不同機器上,可能會造成溢出的問題,可以及時對hash值取余。但是會增加計算開銷,造成hash範圍減小的問題。
為什麽選擇參數33和
33 was chosen because:
1) 乘法易於移位或相加
2) 從移位和加法實現中可以看到,使用33可以復制散列累加器中的大多數輸入位,然後將這些位相對地分散開來。這有助於形成好的雪崩現象。使用較大的移位將復制更少的位,使用較小的移位將使位交互更局部,並使交互擴展所需的時間更長。
3) 32 = 2^5,32 與移 5 位相關,有助於將每一個字符串的每一位比特都作用到最終的哈希值當中
4) 在考慮ASCII字符數據時,5的移位是一個很好的移位量。ASCII字符可以看作是4位字符類型選擇器和4位字符類型選擇器。前4位的數字都是0x3。因此,8位移位將導致具有特定含義的位與具有相同含義的其他位相互作用。4位或2位的移位同樣會在相似的位之間產生強烈的交互作用。5位的移位使得一個字符的4個低階位中的許多位與同一字符的4個上位中的許多強相互作用。
5381 was chosen because
1) 選擇5381並不太重要,很多其他的大的質數數也可以運行地很好。
哈希選擇參考
源自 https://stackoverflow.com/questions/1579721/why-are-5381-and-33-so-important-in-the-djb2-algorithm
djb2不是一個快速哈希函數,因為它每次處理輸入一個字符,並且不嘗試使用指令級並行。
在現代處理器,乘法時該算法要快得多了乘法和其他因素(如2 ^ 13 + 2 ^ 5 + 1)可能也有類似的表現,有更好的輸出,更容易寫。
一個好的非加密哈希函數不希望產生隨機輸出。相反,給定兩個幾乎完全相同的輸入,它希望產生完全不同的輸出。
如果你的輸入值是隨機分布的,你不需要一個好的哈希函數,你可以使用你輸入的任意一組比特。一些現代哈希函數(Jenkins 3, Murmur, probably CityHash)產生的輸出分布比高度相似的隨機輸入更好。
選擇哈希函數的詳細博客 https://blog.csdn.net/xu20082100226/article/details/52651212
djb2:一個產生簡單的隨機分布的哈希函數