Обратное пользовательское базовое кодирование в PHP
У меня есть программа, которая кодирует целые числа в случайные, уникальные, максимум 5 символов строки, используя пользовательский базовый массив. Я хотел бы декодировать эту строку обратно в целое число. Не уверен, как это сделать.
Код:
function intToAlphaBaseN($n, $baseArray) {
$l=count($baseArray);
$s = '';
for ($i = 1; $n >= 0 && $i < 6; $i++) {
$s = $baseArray[($n % pow($l, $i) / pow($l, $i - 1))].$s;
$n -= pow($l, $i);
}
return $s;
}
$alpha=array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7', '8', '9');
$number = 1234;
echo("Number: " . $number . " Converted: " . intToAlphaBaseN($number, $alpha));
Выход: номер: 1234 преобразован: афу
Хотел бы иметь возможность расшифровать что-то вроде "афу".
3 ответа
Нет, вы не можете декодировать строку в число, потому что вы не знаете последнее значение $n
в функции.
Например, последний индекс массива 0
('a'
) а также $i=strlen('afu');
,
0=$n % pow($l, $i) / pow($l, $i - 1)
0=$n % 39304 / 1156
$n=[0,1155]+39304*c;
где c=0,1,2,3...
а также $n
это последнее значение $n
в цикле.
Когда вы найдете последний $n
значение, вы можете найти полный $number
суммируя pow($l, $i) в цикле убывания.
Это полный $n
место между pow($l, 1) + pow($l, 2)
а также pow($l, 1) + pow($l, 2) + pow($l, 3)
,
Попробуй это
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
function intToAlphaBaseN($n,$baseArray) {
$l=count($baseArray);
$s = '';
for ($i = 1; bccomp($n , 0) > 0 ; $i = bcadd($i,1)) {
$s = $baseArray[bcdiv(bcmod($n , bcpow($l, $i)) , bcpow($l, bcsub($i , 1)))].$s;
$n = bcsub($n,bcmul(bcdiv(bcmod($n , bcpow($l, $i)) , bcpow($l, bcsub($i , 1))),bcpow($l, bcsub($i , 1))));
bcadd($i,1);
}
return $s;
}
function alphaBaseNToInt($alpha, $baseArray) {
$result = 0;
$l = count($baseArray);
$alpha = str_split_unicode($alpha,1);
$alpha = array_reverse($alpha);
for ($i = count($alpha) - 1; $i >= 0; $i--) {
$result = bcadd($result, bcmul(array_search($alpha[$i],$baseArray) , bcpow($l,$i)));
}
return $result;
}
$alpha=array( '0','1','2','3','4','5','6','7','8','9',
'A','B','C','Ç','D','E','F','G','Ğ','H','I','İ','J','K','L','M','N','O','Ö','P','Q','R','S','Ş','T','U','Ü','V','W','X','Y','Z');
$listmet = intToAlphaBaseN($string,$alpha);
var_dump($listmet);
$listmet = alphaBaseNToInt($listmet,$alpha);
var_dump($listmet);
я использовал библиотеку bcmath. потому что я работаю очень, очень большие числа. и использовал str_split_unicode для специальных турецких символов.
Возможно, вы изобретаете новый вариант, и, кроме того, вы должны показать нам, что вы действительно пытались реализовать его, прежде чем обращаться за помощью (покажите некоторый код).
Я рекомендую прочитать PHP-документацию base_convert и первые комментарии после документации. http://www.php.net/manual/en/function.base-convert.php
Иначе вот (непроверенная) реализация базового декодирования (после просмотра комментария Джона я не уверен, что ваша функция фактически выполняет базовое кодирование):
function alphaBaseNToInt($alpha, $baseArray) {
$result = 0;
$l = count($baseArray);
for ($i = strlen($alpha) - 1; $i >= 0; --$i)
$result = $result * $l + array_search($alpha[$i], $baseArray);
return $result;
}