2012-10-17 152 views
2

我已經把一個PHP函數如下:爲什麼PHP base_convert會給同一個MYSQL函數一個不同的結果?

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()我回來從RIGHT()的值在匹配MySQL查詢。但是,當我運行CONV()時,我得到了與base_convert()生成的值不同的值。

例如,使用keyword_hash("some keyword")會生成值10923672322315740844.但是,使用SELECT CONV(RIGHT(MD5('some keyword'), 16), 16, 10)會生成10923672322315740475,它顯示最後三個數字不同。

缺少什麼我在這裏?它們不應該產生相同的價值嗎?

+5

[php.net](http://fr2.php.net/manual/en/function.base-convert.php)> base_convert()可能會因爲屬性而失去大數精度與使用的內部「double」或「float」類型有關。請參閱手冊中的浮點數部分以獲取更多具體信息和限制。 – MarcDefiant

+0

爲什麼不試圖用另一種方式來實現數字散列? –

+0

@Mogria Spot on,那是一個很大的幫助,並指出我對這個評論的方向http://fr2.php.net/manual/en/function.base-convert.php#109660,它有一個很棒的功能更精確。剛剛測試過它,並返回相同的值。添加您的評論作爲答案,我會將其標記爲正確。 –

回答

3

我看了一下PHP Manual頁面base_convert()。有以下警告

base_convert()可能會失去對大量精度由於與 到內部「雙重」或「浮動」使用類型屬性。請參閱手冊中的 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庫,支持任意精度的數學,因爲它使用字符串存儲的數字,而不是整數/浮點數等。

相關問題