Может ли кто-нибудь рекомендовать предпочтительный алгоритм для сокращения URL-адресов? Я кодирую с использованием PHP. Первоначально я думал о написании чего-то, что начиналось бы с символа, такого как «a», и повторял бы запросы, создавал записи в базе данных и, следовательно, должен был увеличивать символ до b, c, d … A, B и т. Д. Как подходящее.
Однако мне стало ясно, что этот алгоритм может быть довольно тяжелым / неуклюжим, и может быть лучший способ сделать это.
Я немного читал в Google, и некоторые люди, похоже, делают это с базовым преобразованием из столбца ID базы данных. Это не то, с чем я знаком.
Может кто-нибудь уточнить и объяснить мне, как это будет работать? Пара примеров кода тоже будет отличной.
Я, очевидно, не хочу полного решения, как я хотел бы узнать, сделав это сам, но просто объяснение / псевдокод о том, как это будет работать, будет превосходным.
Большинство сокращающих служб просто используют счетчик, который увеличивается с каждой записью и конвертирует базу с 10 на 64.
Реализация в PHP может выглядеть так:
function encode($number) { return strtr(rtrim(base64_encode(pack('i', $number)), '='), '+/', '-_'); } function decode($base64) { $number = unpack('i', base64_decode(str_pad(strtr($base64, '-_', '+/'), strlen($base64) % 4, '='))); return $number[1]; } $number = mt_rand(0, PHP_INT_MAX); var_dump(decode(encode($number)) === $number);
Функция encode
принимает целочисленное число, преобразует его в байты ( pack
), кодирует его с помощью кодировки Base-64 ( base64_encode
), обрезает конечный padding =
( rtrim
) и заменяет символы +
и /
by -
и _
соответственно ( strtr
). Функция decode
– это обратная функция для encode
и делает полную противоположность (кроме добавления прокрутки).
Дополнительное использование strtr
заключается в том, чтобы перевести исходный алфавит Base-64 в URL и безопасный алфавит с именами файлов как +
и /
должны быть закодированы с помощью кодирования Percentage.
Вы можете использовать функцию base_convert, чтобы сделать базовое преобразование от 10 до 36 с идентификаторами базы данных.
<?php $id = 315; echo base_convert($id, 10, 36), "\n"; ?>
Или вы можете повторно использовать некоторые идеи, представленные в комментариях на странице ниже:
Я использовал для разбиения идентификатора по алгоритму, аналогичному тому, как преобразовать из десятичного в шестнадцатеричный, но он будет использовать 62 символа вместо 16 символов, которые будут использовать hex.
'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', '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'
Например: если вы измените ID = 1234567890, вы получите kv7yl1 в качестве ключа.
Предполагая, что ваш PRIMARY KEY – это INT, и это auto_increments, следующий код заставит вас двигаться =).
<?php $inSQL = "INSERT INTO short_urls() VALUES();"; $inResult = mysql_query($inSQL); $databaseID = base_convert(mysql_insert_id(), 10, 36); // $databaseID is now your short URL ?>
EDIT: Включил base_convert из ответа HGF. Я забыл base_convert в исходном сообщении.
Я принял «легкое» решение. По запросу пользователя я генерирую уникальный идентификатор (проверяющий конфликты в db) с помощью этого snipplet python:
url_hash = base64.b64encode(os.urandom(int(math.ceil(0.75*7))))[:6]
и сохраните его в db.
Собственный PHP base_convert () хорошо работает для небольших диапазонов чисел, но если вам действительно нужно кодировать большие значения, рассмотрите возможность использования чего-то вроде реализации, представленной здесь, которая будет работать на базе 64 и выше, если вы просто предоставите более законные символы для кодирования ,
http://af-design.com/blog/2010/08/10/working-with-big-integers-in-php/
Попробуйте этот метод:
hash_hmac('joaat', "http://www.example.com/long/url/", "secretkey");
Он предоставит вам значение хеша, подходящее для профессионального укороченного урна , например: ' 142ecd53 '