背景:
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~
作者:散漫二丫
链接:https://www.jianshu.com/p/6d85094d2b5b
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦