MySQL / PHP, но больше вопрос по MATH (сокращение сценария)

Для моего последнего проекта мне нужно сократить URL-адреса, которые я затем помещаю в базу данных mysql. Теперь я столкнулся с проблемой, потому что я не знаю, как это решить. По сути, укороченные строки должны выглядеть так (я хочу включить строчные буквы, прописные буквы и цифры)

a
b
...
z
0
...
9
A
...
Z 
aa
ab
ac
...
ba

Итак, 1. URl --> а. Хранится в mysql. В следующий раз новый URL-адрес будет сохранен в -> b, потому что a уже находится в базе данных mysql.

И это все. Но я понятия не имею. Может ли кто-нибудь из вас помочь мне?

Изменить: отформатировано и дальнейшее объяснение.

Это похоже на сервис сокращения URL-адресов imgur.com. Так должно продолжаться до бесконечности (что, я думаю, не нужно...)


person Thomas    schedule 20.09.2011    source источник
comment
Я не совсем понимаю, о чем вы спрашиваете. Вы должны думать о сокращенных URI как о числах с основанием 62, а затем подумать о том, как написать функцию, которая преобразует десятичные числа в ваше представление с основанием 62.   -  person David Alber    schedule 21.09.2011
comment
Я никогда не слышал о base-62. Я немного почитаю о них.   -  person Thomas    schedule 21.09.2011
comment
Base-62 просто означает, что ваша система счисления имеет шестьдесят две уникальные цифры. Общие системы, о которых вы слышали, включают десятичную (с основанием 10) и двоичную (с основанием 2). Взгляните на статью MathWorld на base и статью Википедии на radix для получения дополнительной информации.   -  person David Alber    schedule 21.09.2011


Ответы (1)


Вы можете использовать следующую функцию (код, адаптированный из моего личного фреймворка ):

function Base($input, $output, $number = 1, $charset = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    if (strlen($charset) >= 2)
    {
        $input = max(2, min(intval($input), strlen($charset)));
        $output = max(2, min(intval($output), strlen($charset)));
        $number = ltrim(preg_replace('~[^' . preg_quote(substr($charset, 0, max($input, $output)), '~') . ']+~', '', $number), $charset[0]);

        if (strlen($number) > 0)
        {
            if ($input != 10)
            {
                $result = 0;

                foreach (str_split(strrev($number)) as $key => $value)
                {
                    $result += pow($input, $key) * intval(strpos($charset, $value));
                }

                $number = $result;
            }

            if ($output != 10)
            {
                $result = $charset[$number % $output];

                while (($number = intval($number / $output)) > 0)
                {
                    $result = $charset[$number % $output] . $result;
                }

                $number = $result;
            }

            return $number;
        }

        return $charset[0];
    }

    return false;
}

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

$short_id = Base(10, 62, $auto_increment_id);

Обратите внимание, что первый и второй аргументы определяют базу ввода и вывода соответственно.

Кроме того, я переупорядочил набор символов из «по умолчанию» 0-9a-zA-Z, чтобы он соответствовал вашим примерам.

Вы также можете просто использовать base_convert(), если вы можете жить без регистра смешанного алфавита (база 36).

person Alix Axel    schedule 20.09.2011
comment
@Thomas: Нет проблем, рад помочь. знак равно - person Alix Axel; 21.09.2011