为什么PHP base_convert给同一个MYSQL函数提供了不同的结果?

时间:2012-10-17 14:14:21

标签: php mysql

我把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,其中显示最后三个数字不同。

我在这里缺少什么?它们不应该产生相同的价值吗?

1 个答案:

答案 0 :(得分:3)

我查看了base_convert()的{​​{3}}页面。有以下警告

  由于属性相关,

base_convert()可能会丢失大数字的精度   使用内部“双”或“浮动”类型。请看看   手册中的PHP Manual了解更多信息   具体信息和限制。

后来在Floating point numbers section已找到解决此问题的方法(感谢@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; 
}

此函数使用支持任意精度数学的comments someone库,因为它使用字符串来存储数字而不是整数/浮点数等。