问题:
在开发卡片下发到设备中时,本地数据库存储的十进制的数据,设备刷卡后识别到的是卡片内置16进制数据(例:127800700200878e30018649410123009579),正常处理时采用dechex方法处理,但是发现转换的数据变成了7FFFFFFFFFFFFFFFF
原因:
排查后发现php进制转换方法有最大数值限制(具体可以查看官方文档)
解决方法:
最后采用自己写一个进制转换方法来使用
/**
* @param string $from 需要转换的字符串
* @param int $targetRadix 目标进制
* @param int $fromRadix 源进制 默认10
*/
function radixTransform(string $from, $targetRadix, $fromRadix = 10)
{
/**
* 转换为十进制
* 原理:r进制数abcd转换为十进制则为:a*r^3+b*r^2+c*r^1+d*r^0
*/
// 转换为小写
$from = strtolower($from);
// 获取字符串长度
$fromLenth = strlen($from);
$dec = 0;
for($i = 0; $i < $fromLenth; $i++){
// 获取字符的ASCII码
$asciiCode = ord($from[$i]);
if($asciiCode >= 48 && $asciiCode <= 57){ // 如果是0-9
$asciiNumber = (int)$from[$i];
}elseif($fromRadix > 10 && $asciiCode >= 97 && $asciiCode <= 122){ // 如果是a-z
$asciiNumber = $asciiCode - 87; // - 97 + 10
}else{
throw new Exception("There are characters that are not allowed ['{$from[$i]}' index {$i}]");
}
// php默认计算有大小限制
$dec = bcadd($dec,bcmul($asciiNumber,bcpow($fromRadix,$fromLenth-$i-1)));
}
/**
* 转换为目标进制
* 原理:上面的原理反转过来理解
*/
$result = '';
while($dec > 0){
$remainder = bcmod($dec,$targetRadix);
$result = dechex($remainder).$result;
$dec = bcdiv(bcsub($dec,$remainder),$targetRadix);
}
return $result;
}