Преобразование между десятичным числом и основанием 36

Я хочу преобразовать числа в базу 36 с помощью PHP. Функция base_convert не работает, потому что я хочу преобразовать большие числа: я не получу исходное число, если снова преобразую его из 36-кратного в десятичное.

Я попробовал некоторые функции, представленные на нескольких веб-сайтах, но никогда не получаю такого же результата. Кроме того, эти два веб-сайта (в Javascript) дают одинаковый результат:

Например, 1010701001118000000000000000 нужно преобразовать в 3IZS0ZE1RQ68W8SSW4.

Вот функции, которые я пробовал (и которые не работают):


person Yoone    schedule 06.05.2012    source источник
comment
почему бы не преобразовать ваше число в строку, а затем закодировать с помощью base64?   -  person    schedule 06.05.2012
comment
Идея состоит в том, чтобы уменьшить длину числа.   -  person Yoone    schedule 06.05.2012
comment
Вам нужно преобразовать число обратно в десятичное в какой-то момент?   -  person Niko    schedule 06.05.2012
comment
Да, я знаю, число в базе 36 просто здесь для обмена, мне нужно получить его в десятичном виде в конце (не зная функции, используемой для преобразования в базу 36).   -  person Yoone    schedule 06.05.2012


Ответы (2)


Вот две простые функции, использующие алгоритм, найденный в Википедии, при этом используя bcmath для правильного расчета даже очень больших чисел:

function fromDecimalToBase($in, $to) {
    $in = (string) $in;
    $out = '';

    for ($i = strlen($in) - 1; $i >= 0; $i--) {
        $out = base_convert(bcmod($in, $to), 10, $to) . $out;
        $in = bcdiv($in, $to);
    }

    return preg_replace('/^0+/', '', $out);
}

function fromBaseToDecimal($in, $from) {
    $in = (string) $in;
    $out = '';

    for ($i = 0, $l = strlen($in); $i < $l; $i++) {
        $x = base_convert(substr($in, $i, 1), $from, 10);
        $out = bcadd(bcmul($out, $from), $x);
    }

    return preg_replace('/^0+/', '', $out);
}

Однако я получаю 3izs0ze1rq66tifrpc за указанный вами номер — может быть, вы ошиблись при преобразовании?

person Niko    schedule 06.05.2012
comment
Вы получаете тот же результат, что и в другом ответе, возможно, преобразователи Javascript ошибаются... Но я не знаю, как это выяснить. Возможно, мне придется найти идеальный конвертер, чтобы знать... - person Yoone; 06.05.2012
comment
@Yoone Я добавил преобразование обратно в десятичное число, и, похоже, пока оно работает. - person Niko; 06.05.2012
comment
Но я могу использовать только первый и просто поменять местами $from и $to :). Как бы то ни было, я вижу, что вы используете функцию PHP base_convert, поэтому я думаю, что ваше преобразование является правильным. Я приму ваш ответ, спасибо! - person Yoone; 06.05.2012
comment
Разница между двумя функциями в основном заключается в том, что первая вычисляет % и / в исходной системе, а вторая вычисляет + и * в целевой системе. Поскольку bcmath может обрабатывать только десятичные числа, вам нужно будет использовать первое для перехода от десятичного к любому другому основанию (так что десятичное число является исходной системой), а второе — для возврата из любого основания к десятичному (десятичное = целевое). -система). - person Niko; 06.05.2012

http://www.pgregg.com/projects/php/base_conversion/base_conversion.php

На этой странице показано, как преобразовать числа произвольной длины между разными основаниями. Я попробовал ваш пример, и похоже, что он работает в обоих направлениях. Исходный код, написанный на PHP, доступен.

person JK.    schedule 06.05.2012
comment
Я не знаю, какой код правильный, но по вашей ссылке я получаю 3IZS0ZE1RQ66TIFRPC вместо 3IZS0ZE1RQ68W8SSW4 - person Yoone; 06.05.2012