Реализация PHP для алгоритма сокращения URL - PullRequest
0 голосов
/ 01 февраля 2011

Я нашел Ответ Марселя Джекверта на Как закодировать сокращение URL? , чтобы быть хорошим ответом на проблему, однако мой вопрос - как это будет выглядеть в PHP? Вот ответ Марселя :


Вам нужна Биективная функция f (не должно быть x1 != x2, что составит f(x1) = f(x2); и для каждого y вы найдете x, так что f(x)=y). Это необходимо для того, чтобы вы могли найти обратную функцию g('abc') = 123 для вашей функции f(123)='abc'.

Я бы продолжил ваш подход "преобразования числа в строку" (однако вы поймете, что ваш предложенный алгоритм не будет работать, если ваш id равен простое и больше 52).

Как преобразовать id в сокращенный URL:

  • Подумайте об алфавите, который вы хотите использовать. В вашем случае это [a-zA-Z0-9]. Содержит 62 буквы.
  • Возьмите автоматически сгенерированный уникальный цифровой ключ (с автоинкрементом id): например, 125 (десятичное число)
  • Теперь вам нужно конвертировать 125 (основание 10) в X (основание 62). Тогда это будет {2} {1} (2 раза; 62 + 1 = 125).
  • Теперь сопоставьте символы {2} и {1} с вашим алфавитом. Скажите {0} = 'a', {25} = 'z' и так далее. У нас будет {2} = 'c' и {1} = 'b'. Таким образом, '/ cb' будет вашим сокращенным URL.

Как преобразовать сокращенный URL abc в начальный id:

  • Если вы хотите сделать это наоборот, это не совсем сложно. «e9a» будет преобразовано в «4-ю, 61-ю, 0-ю букву в алфавите» = {4} {61} {0}, то есть 4 & times; 62 & times; 62 + 61 & times; 62 + 0 = 19158. Затем вам просто нужно будет найдите вашу базу данных с помощью id 19158.

Ответы [ 4 ]

1 голос
/ 01 февраля 2011
function convert($src, $srcAlphabet, $dstAlphabet) {
    $srcBase = strlen($srcAlphabet);
    $dstBase = strlen($dstAlphabet);

    $wet = $src;
    $val = 0;
    $mlt = 1;

    while ($l = strlen($wet)) {
        $digit = $wet[$l - 1];
        $val += $mlt * strpos($srcAlphabet, $digit);
        $wet = substr($wet, 0, $l - 1);
        $mlt *= $srcBase;
    }

    $wet = $val;
    $dst = '';

    while ($wet >= $dstBase) {
        $digitVal = $wet % $dstBase;
        $digit = $dstAlphabet[$digitVal];
        $dst = $digit . $dst;
        $wet /= $dstBase;
    }

    $digit = $dstAlphabet[$wet];
    $dst = $digit . $dst;

    return $dst;
}

// prints cb
print convert('125', '0123456789', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');

// prints 19158
print convert('e9a', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', '0123456789');
0 голосов
/ 08 сентября 2016

Основная проблема решения Марселя заключается в том, что в качестве заполнителя используется ноль.При преобразовании между основаниями неизбежно, что число, выбранное для представления 0, не может появиться в начале преобразованного числа.

Например, если вы преобразуете целые числа 10 из 10 в основание 4, используя «ABCD», используя предоставленный механизм, нет способа получить вывод, который начинается с буквы «А», так как он представляет ноль в новой базе и не будет префиксом числа.Вы можете ожидать, что 5 будет «AA», но вместо этого это «BA».Нет никакого способа принудить этот алгоритм к созданию "AA", потому что это было бы похоже на запись "00" в десятичном виде, который имеет то же значение, что и "0".

Вот альтернативное решение в PHP, которое используетвся гамма:

function encode($n, $alphabet = 'ABCD') {
    $output = '';

    if($n == 0) {
        $output = $alphabet[0];
    }
    else {
        $digits = floor(log($n, strlen($alphabet))) + 1;

        for($z = 0; $z < $digits; $z++) {
            $digit = $n % 4;
            $output = $alphabet[$digit] . $output;
            $n = floor($n / 4) - 1;
        }
    }
    return $output;
}

function decode($code, $alphabet = 'ABCD') {
    $n = 0;
    $code = str_split($code);
    $unit = 1;
    while($letter = array_pop($code)) {
        $n += (strpos($alphabet, $letter) + 1) * $unit;
        $unit = $unit * strlen($alphabet);
    }

    return $n - 1;
}

echo encode(25); // should output "ABB"
echo decode('ABB'); // should output 25

Изменить / передать второй параметр в список символов для использования вместо короткого 4-символьного словаря "ABCD".

0 голосов
/ 13 февраля 2012

Мне нравится эта функция PHP, которая позволяет вам настраивать алфавит (и удалять запутанные 0 / O и т.

0 голосов
/ 01 февраля 2011

все, что вам нужно сделать, это конвертировать между различными базовыми системами базы 10 в базу 62

https://github.com/infinitas/infinitas/blob/dev/core/short_urls/models/short_url.php

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...