php字串雜湊函數演算法實現代碼

來源:互聯網
上載者:User
  1. function DJBHash($str) // 0.22
  2. {
  3. $hash = 0;
  4. $n = strlen($str);
  5. for ($i = 0; $i <$n; $i++)
  6. {
  7. $hash += ($hash <<5 ) + ord($str[$i]);
  8. }
  9. return $hash % 701819;
  10. }
  11. function ELFHash($str) // 0.35
  12. {
  13. $hash = $x = 0;
  14. $n = strlen($str);
  15. for ($i = 0; $i <$n; $i++)
  16. {
  17. $hash = ($hash <<4) + ord($str[$i]);
  18. if(($x = $hash & 0xf0000000) != 0)
  19. {
  20. $hash ^= ($x>> 24);
  21. $hash &= ~$x;
  22. }
  23. }
  24. return $hash % 701819;
  25. }
  26. function JSHash($str) // 0.23
  27. {
  28. $hash = 0;
  29. $n = strlen($str);
  30. for ($i = 0; $i <$n; $i++)
  31. {
  32. $hash ^= (($hash <<5) + ord($str[$i]) + ($hash>> 2));
  33. }
  34. return $hash % 701819;
  35. }
  36. function SDBMHash($str) // 0.23
  37. {
  38. $hash = 0 ;
  39. $n = strlen($str);
  40. for ($i = 0; $i <$n; $i++)
  41. {
  42. $hash = ord($str[$i]) + ($hash <<6 ) + ($hash <<16 ) - $hash;
  43. }
  44. return $hash % 701819;
  45. }
  46. function APHash($str) // 0.30
  47. {
  48. $hash = 0 ;
  49. $n = strlen($str);
  50. for ($i = 0; $i <$n; $i++)
  51. {
  52. if (($i & 1 ) == 0 )
  53. {
  54. $hash ^= (($hash <<7 ) ^ ord($str[$i]) ^ ($hash>> 3 ));
  55. }
  56. else
  57. {
  58. $hash ^= ( ~ (($hash <<11 ) ^ ord($str[$i]) ^ ($hash>> 5)));
  59. }
  60. }
  61. return $hash % 701819;
  62. }
  63. function DEKHash($str) // 0.23
  64. {
  65. $n = strlen($str);
  66. $hash = $n;
  67. for ($i = 0; $i <$n; $i++)
  68. {
  69. $hash = (($hash <<5) ^ ($hash>> 27)) ^ ord($str[$i]);
  70. }
  71. return $hash % 701819;
  72. }
  73. function FNVHash($str) // 0.31
  74. {
  75. $hash = 0;
  76. $n = strlen($str);
  77. for ($i = 0; $i <$n; $i++)
  78. {
  79. $hash *= 0x811C9DC5;
  80. $hash ^= ord($str[$i]);
  81. }
  82. return $hash % 701819;
  83. }
  84. function PJWHash($str) // 0.33
  85. {
  86. $hash = $test = 0;
  87. $n = strlen($str);
  88. for ($i = 0; $i <$n; $i++)
  89. {
  90. $hash = ($hash <<4) + ord($str[$i]);
  91. if(($test = $hash & -268435456) != 0)
  92. {
  93. $hash = (( $hash ^ ($test>> 24)) & (~-268435456));
  94. }
  95. }
  96. return $hash % 701819;
  97. }
  98. function PHPHash($str) // 0.34
  99. {
  100. $hash = 0;
  101. $n = strlen($str);
  102. for ($i = 0; $i <$n; $i++)
  103. {
  104. $hash = ($hash <<4) + ord($str[$i]);
  105. if (($g = ($hash & 0xF0000000)))
  106. {
  107. $hash = $hash ^ ($g>> 24);
  108. $hash = $hash ^ $g;
  109. }
  110. }
  111. return $hash % 701819;
  112. }
  113. function OpenSSLHash($str) // 0.22
  114. {
  115. $hash = 0;
  116. $n = strlen($str);
  117. for ($i = 0; $i <$n; $i++)
  118. {
  119. $hash ^= (ord($str[$i]) <<($i & 0x0f));
  120. }
  121. return $hash % 701819;
  122. }
  123. function MD5Hash($str) // 0.050
  124. {
  125. $hash = md5($str);
  126. $hash = $hash[0] | ($hash[1] <<8 ) | ($hash[2] <<16) | ($hash[3] <<24) | ($hash[4] <<32) | ($hash[5] <<40) | ($hash[6] <<48) | ($hash[7] <<56);
  127. return $hash % 701819;
  128. }
複製代碼

演算法說明:函數後面注釋中是我本地測試的執行1000次的速度(單位:s),可以看出來MD5Hash是最快的,而且要比其他函數快很多很多...但是從這個函數的演算法也可以看出來,它僅僅是依賴於md5後字串的前7個字元,也就是說如果前7個字元相同的話那麼獲得的hash值是完全一樣的,所以實際來說它的分布情況是不太令人信任的....如果按照32個字元來計算的話速度那就遠遠的慢於其他演算法了...

除了MD5Hash,其他演算法都會受到字串長度的影響,越長越慢,我測試用的是10個字元的英文。每個函數最後的 return $hash % 701819; 中 701819 表示是雜湊的最大容積,也就是說這些雜湊函數最後得到的數字範圍是0~701819,這個數字是可以改的一般認為使用一個大的質數結果的分布會是比較均勻的,在 701819 附近的幾個建議的值是:175447, 350899, 1403641, 2807303, 5614657。

這個到底可以用來做什麼呢...

為什麼要整理 and 測試這些雜湊演算法,我在寫多使用者 Blog,恩...之前的日誌裡面也有提過,多使用者 Blog 一般都有一個功能,那就是使用一個英文和數字組合的使用者名稱來作為 Blog 的地址(次層網域或者目錄)。那麼就有一個問題了,如何根據使用者名稱來擷取使用者的 ID,多一次查詢嗎?有了雜湊函數就不用了,使用雜湊函數處理使用者名稱,得到一個數字,再對數字做一定的處理(我是按照2位分割成層次的目錄,目的是防止一個目錄下有太多的檔案而影響磁碟檢索速度),然後就形成了一個路徑,把對應的ID儲存在這個路徑下的檔案內(我個人推薦使用者名稱做檔案名稱),這樣就可以根據使用者名稱來直接獲得使用者的ID,不需要查詢,使用者名稱做檔案名稱,所以即使最後結果相同也是在不同的檔案中,所以可以不用擔心出現碰撞。

當然...如果你的系統完全是根據使用者名稱來操作那當我前面這些都沒說 = =b,悄悄的非議一句 SELECT 也是數字比字串要快一些地。

我選擇的是DJB演算法,等以後上線後如果測試MD5分布還算可以接受的話再考慮換用。

從這裡也可以看出來其實雜湊對於分布還是很有用地,呵呵,可以用來作緩衝,靜態或者其他需要分布儲存的東西上面。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.