簡體   English   中英

該哈希函數背后的原理是什么?

[英]What's the rationale behind this hash function?

uint32_t h(const char *kbuf, int ksiz){
  uint32_t hash = 751;
  const char *rp = kbuf + ksiz;
  while(ksiz--){
    hash = (hash * 31) ^ *(uint8_t *)--rp;
  }
  return hash;
}

為什么要用這種方式計算哈希,這是什么原理?

您的哈希算法遵循相同的思想,該思想導致修改后的Bernstein哈希和Fowler / Noll / Vo(例如,參見現有哈希算法的此概述 )。

XORing字節是一種經典的哈希算法。 但是,結果散列值的分布遠非最佳,因此添加了一個額外的混合步驟(在這種情況下乘以31 )。

Josh Bloch在Effective Java中解釋了使用31作為乘數:

選擇值31是因為它是奇數質數。 如果是偶數且乘法運算溢出,則信息將丟失,因為乘以2等於移位。 使用質數的優勢尚不清楚,但這是傳統的。 31的一個不錯的特性是乘法可以用移位和減法來代替,以獲得更好的性能:31 * i ==(i << 5)-i。 現代VM自動執行這種優化。

在原始的伯恩斯坦散列中選擇33作為乘數可能是遵循類似的推理。 但是,如果您不是主要關注散列性能,則選擇乘數可帶來更好的分布可能會更好。 如果您不想嘗試自己,Fowler / Noll / Vo可能是一個不錯的選擇。

此實現嘗試使輸入到輸出的映射統一,以使沖突也統一。 換句話說,它試圖避免這樣的情況,即對於某些哈希值,與其他哈希值相比,存在許多沖突的方法。 它通過將原始偽隨機數生成器的值混入結果哈希值來實現。 或者,您也可以反過來考慮它,例如將PRNG混入輸入數據中。 質數(751和31)有助於實現均勻性。 當然,我們無法保證,如果精心選擇輸入,您將無視這些嘗試。

有關更多詳細信息,請參閱以下文章:
哈希函數-均勻性
線性同余發生器

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM