php字串雜湊函數演算法實作程式碼

WBOY
發布: 2016-07-25 08:54:30
原創
1362 人瀏覽過
  1. 函數 DJBHash($str) // 0.22
  2. {
  3. $hash = 0;
  4. $n = strlen($str);
  5. for ($i = 0; $i {
  6. $hash = ($hash }
  7. return $hash % 701819;
  8. }
  9. function ELFHash($str) // 0.35
  10. {
  11. $hash = $x = 0;
  12. $n = strlen($ str);
  13. for ($i = 0; $i {
  14. $hash = ($hash if(($x = $hash & 0xf0000000) != 0)
  15. {
  16. $hash ^= ($x>> 24);
  17. $ hash &= ~$x;
  18. }
  19. }
  20. return $hash % 701819;
  21. }
  22. 函數JSHash($str) // 0.23
  23. {
  24. $hash = 0;$n = strlen($str);
  25. for ($i = 0; $i {
  26. $hash ^ = (($hash > 2));
  27. }
  28. 回傳$hash % 701819;
  29. }
  30. function SDBMHash($str) // 0.23
  31. {
  32. $hash = 0 ;
  33. $n = strlen($str);
  34. for ($i = 0; $i {
  35. $hash = ord($str[$i]) ($hash }
  36. return $hash % 701819;
  37. }
  38. function APHash($str) // 0.30
  39. {
  40. $hash = 0 ;
  41. $ strlen($str);
  42. for ($i = 0; $i {
  43. if (($i & 1 ) == 0 )
  44. {
  45. $hash ^= (($hash > 3 ));
  46. }
  47. else
  48. {
  49. $hash ^= ( ~ (($hash > 5)));
  50. }
  51. }
  52. 回傳$hash % 701819;
  53. }
  54. 函數DEKHash($str) // 0.23
  55. {
  56. $n = strlen($str);
  57. $hash = $n
  58. ;
  59. ;
  60. ;
  61. ;
  62. ;
  63. ;
  64. ;
  65. ;
  66. ;
  67. ;
  68. ;
  69. ;
  70. ;
  71. ;
  72. ;
  73. ;
  74. ;
  75. ;
  76. ;
  77. ;
  78. ;
  79. ;
  80. ;
  81. ;
  82. for ($i = 0; $i {
  83. $hash = (($hash > 27)) ^ ord($ str[$i]);
  84. }
  85. 回傳$hash % 701819;
  86. }
  87. 函數FNVHash($str) // 0.31
  88. {
  89. $hash = 0 ;
  90. $n = strlen($str);
  91. for ($i = 0; $i {
  92. $hash *= 0x811C9DC5;
  93. $hash ^= ord($str[$i]) ;
  94. }
  95. return $hash % 701819;
  96. }
  97. 函數PJWHash($str) // 0.33
  98. {
  99. $hash = $test = 0 ;
  100. $n = strlen($str);
  101. for ($i = 0; $i {
  102. $hash = ($hash
  103. if(($test = $hash & -268435456) != 0)
  104. {
  105. $hash = (($雜湊^($test>> 24)) & (~-268435456));
  106. }
  107. }
  108. 回傳$hash % 701819 ;
  109. }
  110. 函數PHPHash($str) // 0.34
  111. {
  112. $hash = 0;
  113. $n = strlen($str);
  114. 對於($i = 0; $i {
  115. $hash = ($hash if (($g = ($hash & 0xF0000000)))
  116. {
  117. $hash = $hash ^ ($g>>24);
  118. $hash = $hash ^ $g;
  119. }
}
return $hash % 701819; }
函數 OpenSSLHash($str) // 0.22{$hash = 0;$n = strlen($str); for ($i = 0; $i {$hash ^= (ord($str[$i]) } return $hash % 701819;} function MD5Hash($str) // 0.050{$hash = md5($str); $連續= $哈希[0] | ($hash[1] return $hash % 701819;}複製程式碼

演算法說明: 函數後面註解中是我本地測試的執行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分佈還算可以接受的話再考慮換用。

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



來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!