DJBX33A (Daniel J. Bernstein, Times 33 with Addition) APR哈希默認算法

經典是經過了時間考驗的

  1. APR_DECLARE_NONSTD(unsigned  int ) apr_hashfunc_default( const   char  *char_key,  
  2.                                                       apr_ssize_t *klen)  
  3. {  
  4.     unsigned int  hash = 0;  
  5.     const  unsigned  char  *key = ( const  unsigned  char  *)char_key;  
  6.     const  unsigned  char  *p;  
  7.     apr_ssize_t i;  
  8.       
  9.     /*  
  10.      * This is the popular `times 33' hash algorithm which is used by  
  11.      * perl and also appears in Berkeley DB. This is one of the best  
  12.      * known hash functions for strings because it is both computed  
  13.      * very fast and distributes very well.  
  14.      *  
  15.      * The originator may be Dan Bernstein but the code in Berkeley DB  
  16.      * cites Chris Torek as the source. The best citation I have found  
  17.      * is "Chris Torek, Hash function for text in C, Usenet message  
  18.      * <[email protected]> in comp.lang.c , October, 1990." in Rich  
  19.      * Salz's USENIX 1992 paper about INN which can be found at  
  20.      * <http://citeseer.nj.nec.com/salz92internetnews.html>.  
  21.      *  
  22.      * The magic of number 33, i.e. why it works better than many other  
  23.      * constants, prime or not, has never been adequately explained by  
  24.      * anyone. So I try an explanation: if one experimentally tests all  
  25.      * multipliers between 1 and 256 (as I did while writing a low-level  
  26.      * data structure library some time ago) one detects that even  
  27.      * numbers are not useable at all. The remaining 128 odd numbers  
  28.      * (except for the number 1) work more or less all equally well.  
  29.      * They all distribute in an acceptable way and this way fill a hash  
  30.      * table with an average percent of approx. 86%.  
  31.      *  
  32.      * If one compares the chi^2 values of the variants (see  
  33.      * Bob Jenkins ``Hashing Frequently Asked Questions'' at  
  34.      * http://burtleburtle.net/bob/hash/hashfaq.html for a description  
  35.      * of chi^2), the number 33 not even has the best value. But the  
  36.      * number 33 and a few other equally good numbers like 17, 31, 63,  
  37.      * 127 and 129 have nevertheless a great advantage to the remaining  
  38.      * numbers in the large set of possible multipliers: their multiply  
  39.      * operation can be replaced by a faster operation based on just one  
  40.      * shift plus either a single addition or subtraction operation. And  
  41.      * because a hash function has to both distribute good _and_ has to  
  42.      * be very fast to compute, those few numbers should be preferred.  
  43.      *  
  44.      *                  -- Ralf S. Engelschall <[email protected]>  
  45.      */   
  46.        
  47.     if  (*klen == APR_HASH_KEY_STRING) {  
  48.         for  (p = key; *p; p++) {  
  49.             hash = hash * 33 + *p;  
  50.         }  
  51.         *klen = p - key;  
  52.     }  
  53.     else  {  
  54.         for  (p = key, i = *klen; i; i--, p++) {  
  55.             hash = hash * 33 + *p;  
  56.         }  
  57.     }  
  58.     return  hash;  
  59. }  

對函數註釋部分的翻譯:
這是很出名的times33哈希算法,此算法被perl語言採用並在Berkeley DB中出現.它是已知的最好的哈希算法之一,在處理以字符串爲鍵值的哈希時,有着極快的計算效率和很好哈希分佈.最早提出這個算法的是Dan Bernstein,但是源代碼確實由Clris Torek在Berkeley DB出實作的.我找到的最確切的引文中這樣說"Chris Torek,C語言文本哈希函數,Usenet消息<<[email protected]> in comp.lang.c ,1990年十月."在Rich Salz於1992年在USENIX報上發表的討論INN的文章中提到.這篇文章可以在<http://citeseer.nj.nec.com /salz92internetnews.html>上找到.

33這個奇妙的數字,爲什麼它能夠比其他數值效果更好呢?無論重要與否,卻從來沒有人能夠充分說明其中的原因.因此在這裏,我來試着解釋一下.如果某人試 着測試1到256之間的每個數字(就像我前段時間寫的一個底層數據結構庫那樣),他會發現,沒有哪一個數字的表現是特別突出的.其中的128個奇數(1除 外)的表現都差不多,都能夠達到一個能接受的哈希分佈,平均分佈率大概是86%.

如果比較這128個奇數中的方差值(gibbon:統計術語,表示隨機變量與它的數學期望之間的平均偏離程度)的話(見Bob Jenkins的<哈希常見疑問>http://burtleburtle.net/bob/hash/hashfaq.html,中對平方 差的描述),數字33並不是表現最好的一個.(gibbon:這裏按照我的理解,照常理,應該是方差越小穩定,但是由於這裏不清楚作者方差的計算公式,以 及在哈希離散表,是不是離散度越大越好,所以不得而知這裏的表現好是指方差值大還是指方差值小),但是數字33以及其他一些同樣好的數字比如 17,31,63,127和129對於其他剩下的數字,在面對大量的哈希運算時,仍然有一個大大的優勢,就是這些數字能夠將乘法用位運算配合加減法來替 換,這樣的運算速度會提高.畢竟一個好的哈希算法要求既有好的分佈,也要有高的計算速度,能同時達到這兩點的數字很少.

發佈了168 篇原創文章 · 獲贊 5 · 訪問量 54萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章