我将一个PHP函数组合在一起,如下所示:
function keyword_hash($keyword) {
return base_convert(substr(md5($keyword), -16), 16, 10);
}这个函数的目的是生成一个我可以存储在数据库中的数字散列值,并将其用于查找(而不是试图对关键字列进行索引)。
MySQL中此函数的等价物如下所示:
SELECT CONV(RIGHT(MD5('some keyword'), 16), 16, 10);我已经验证了MD5字符串是相同的,并且substr()与我在MySQL查询中从RIGHT()返回的值相匹配。但是,当我运行CONV()时,我得到的值与从base_convert()生成的值不同。
例如,使用keyword_hash("some keyword")会生成值10923672322315740844。但是,使用SELECT CONV(RIGHT(MD5('some keyword'), 16), 16, 10)会生成10923672322315740475,这会显示后三个数字不同。
这里我漏掉了什么?它们不应该产生相同的价值吗?
发布于 2012-10-18 01:55:54
我看了一下base_convert()的PHP Manual页面。有以下警告
由于与所使用的内部“base_convert()”或"float“类型相关的属性,
float可能会在大数字上失去精度。有关更具体的信息和限制,请参阅手册中的Floating point numbers section。
后来在comments someone中已经找到了这个问题的解决方案(感谢@CraigSefton):
function str_baseconvert($str, $frombase=10, $tobase=36) {
$str = trim($str);
if (intval($frombase) != 10) {
$len = strlen($str);
$q = 0;
for ($i=0; $i<$len; $i++) {
$r = base_convert($str[$i], $frombase, 10);
$q = bcadd(bcmul($q, $frombase), $r);
}
}
else $q = $str;
if (intval($tobase) != 10) {
$s = '';
while (bccomp($q, '0', 0) > 0) {
$r = intval(bcmod($q, $tobase));
$s = base_convert($r, 10, $tobase) . $s;
$q = bcdiv($q, $tobase, 0);
}
}
else $s = $q;
return $s;
}该函数使用bc math库,该库支持任意精度的数学运算,因为它使用字符串而不是整数/浮点数等来存储数字。
https://stackoverflow.com/questions/12936355
复制相似问题