Как подтвердить, что строка является действительным base36 от целого числа? - PullRequest
1 голос
/ 05 июня 2011

У меня был такой код:

$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 или нет.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 05 июня 2011

Как видите, строка "myalias" просто печатается в самой версии PHP для Linux.

И это правильное поведение .Вы получаете другие результаты на своем Mac - потому что он 32-битный, а ваш номер усекается до 2147483647 (2^32 - 1)

if (preg_match('~^[a-z\d]+$~', $string)) {
    // valid base36
}
1 голос
/ 05 июня 2011

Проблема, с которой вы столкнулись, состоит в том, что одна из ваших машин работает с 32-битным целым числом со знаком (первый), а другая - с 64-битным целым числом со знаком (или, возможно, больше) в этом преобразовании intval. [См. inval документы для диапазонов.]

myalias, преобразованные из Base36, превышают 0x7FFFFFFF (максимальное 32-разрядное значение со знаком), в то время как это точно с 64-разрядным целым числом со знаком (0xba204c1e4 == 49962861028). Таким образом, тот, который вы считаете «сломанным» (linux), на самом деле является правильной версией. Первый не работает из-за переполнения.

Каждая строка, состоящая из 0-9a-z символов, является действительным числом Base36. Единственная проверка, которую вы можете сделать, - это проверка того, что все символы в строке находятся в допустимом диапазоне (и проверка на переполнение (проверьте, является ли возвращаемое значение максимальным int) - ненадежно).

...