php哈希分表過程中出現大整型數據溢出問題的解決

php哈希分表過程中出現大整型數據溢出問題的解決

 

背景:
python腳本監控數據進行哈希分表,方案如下:

    ```
        def gethashcode(str):
              import hashlib
              m = hashlib.md5()
              m.update(str)
              hashcode = m.hexdigest()
              return int(hashcode, 16)
    ```

如上腳本哈希分表,key落入哪個分表,獲取的時候就從哪個分表取出。後臺PHP在實現匹配分表時要翻譯實現python的哈希分表方案。最初方案如下:

      ```
        function gethashcode($k)
        {
            $hashcode = md5($k);//獲取32爲16進制字符串
            return hexdec($hashcode);//將16進制字符串轉爲十進制數字
         }

      ```

如上PHP實現內容會出現PHP大整型數據溢出問題,最後對table_nums進行取模的時候會發生異常。改良原理如下:

      ```
      如果用一個int 型數據保存. 逐步解釋每一個字符乘以16^n的值再累加, 把字符串轉化成數字 再 mod 10的話,會存在溢出的      問題, 所以這種思路不太好.
      自己能想到最好的辦法是這樣的:讀出每一個字符對應的於0~15的值(除最後一位)累加乘以6,再加上最後一位的值. 之後再 mod10 即是最終所求的餘數..
      原理:16^n = 10*k +6 (n,k爲正整數,且n>=1) 這個式中顯然成立.. 因此 (16^n)mod(10) = (10*k + 6)mod(10) = 6(n,k爲正整數,且n>=1).
       因此除最後一位的數.都可以直接簡化爲乘以6,再加了最後一位的值. 最後mod 10即可.
       示例: 比如 0x58fd7 mod 10 = ?
       直接口算易知:(5 + 8 + 15 + 13)* 6 + 7 的結果mod10 爲 3 。。 有此方法上面的式中很長都可以很快口算出來.何況用編程for循環呢..

      ```

以上原理參考文章:https://blog.csdn.net/w_sx12553/article/details/17526917
原理對應方案:

      ```
       function gethashcode($k)
        {
              $m16 = md5($k);
              $m10 = 0;
              for ($i=0; $i < strlen($m16); $i++) { 
                    if($i == strlen($m16)-1) break;
                    $m10 += hexdec($m16[$i]);
               }
               $m10 = $m10*6+hexdec($m16[$i]);
               return $m10;
      }

      

      $mod = $m10%table_nums;
      ```

over~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章