如何确认字符串是有效的,以36为基数的整数


How to confirm that a string is valid base36 of an integer?

我有这样的代码:

$alias = 'myalias';
echo "<pre>";
echo "
ALIAS: $alias
ROUND: ", intval($alias, 36) , "'n" ,
"AGAIN: ", base_convert(intval($alias, 36), 10, 36)
;
echo "<hr>";
$alias = '27xk3q';
echo "<pre>";
echo "
ALIAS: $alias
ROUND: ", intval($alias, 36) , "'n" ,
"AGAIN: ", base_convert(intval($alias, 36), 10, 36)
;

这曾经是有效的,现在在我的家用Mac电脑上仍然有效。输出为:

ALIAS: myalias
ROUND: 2147483647
**AGAIN: zik0zj**
ALIAS: 27xk3q
ROUND: 134255366
AGAIN: 27xk3q

但当我把它上传到我的Linux服务器时,它会产生不同的效果!

ALIAS: myalias
ROUND: 49962861028
**AGAIN: myalias**
ALIAS: 27xk3q
ROUND: 134255366
AGAIN: 27xk3q

正如您所看到的,"myalias"字符串在PHP的Linux版本中只是打印为其本身。

如果这不起作用或是错误的代码,我需要知道一种简单的方法来检查字符串是否是有效的base36版本的整数。

谢谢!

正如您所看到的,"myalias"字符串在PHP的Linux版本中只是打印为其本身。

这是正确的行为。你在mac上得到了另一个结果,因为它是32位的,你的号码被截断为21474836472^32 - 1

if (preg_match('~^[a-z'd]+$~', $string)) {
    // valid base36
}

您遇到的问题是,您的一台机器在intval转换上使用32位有符号int(第一台),另一台机器使用64位有符号整数(或可能更大)。[有关范围,请参阅inval文档。]

从Base36转换的myalias超过0x7FFFFFFF(最大有符号32位值),而它与64位有符号int(0xba204c1e4==49962861028)完全相同。因此,您认为"坏了"的版本(linux版本)实际上是正确的版本。第一个由于溢出而无法工作。

每个由0-9a-z个字符组成的字符串都是一个有效的Base36数字。唯一可以做的检查是检查字符串中的所有字符是否都在有效范围内,(并检查溢出(测试返回的值是否为最大int)-不可靠)。