Как сгенерировать неуловимый "крошечный URL" на основе идентификатора? - PullRequest
6 голосов
/ 07 августа 2010

Я заинтересован в создании крошечных ссылок, похожих на URL.Моя идея состояла в том, чтобы просто сохранить инкрементный идентификатор для каждого размещенного длинного URL, а затем преобразовать этот идентификатор в его базовый вариант 36, как показано в PHP:

$tinyurl = base_convert($id, 10, 36)

Проблема здесь в том, что результат является предположительным,в то время как трудно угадать, каким будет следующий URL, при этом он будет коротким (крошечным).Например.атм, если мой последний tinyurl был a1, следующий будет a2.Это плохо для меня.

Итак, как мне убедиться, что получающийся крошечный URL-адрес не настолько предсказуем, но все же короткий?

Ответы [ 9 ]

9 голосов
/ 07 августа 2010

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

Вы должны решить, насколько важны оба для вас.Другой вопрос заключается в том, хотите ли вы, чтобы последовательные URL-адреса были предположимыми или не были достаточно случайными, чтобы затруднить угадывание любого действительного URL-адреса.

По сути, вы хотите объявить n из N действительных идентификаторов.Выберите N меньше, чтобы сделать URL-адреса короче, и уменьшите n, чтобы создать URL-адреса, которые трудно угадать.Увеличьте n и N, чтобы генерировать больше URL, когда берутся более короткие.

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

5 голосов
/ 07 августа 2010

Я хотел бы просто crc32 url

$url = 'http://www.google.com';
$tinyurl = hash('crc32', $url ); // db85f073

минусы: константа 8 символов длиной идентификатор

4 голосов
/ 07 августа 2010

Это действительно дешево, но если пользователь не знает, что это происходит, то это не так легко предположить, но префикс и постфикс фактического идентификатора с 2 или 3 случайными числами / буквами.Я не думаю, что dm2a2dq2 был следующим в серии.

2 голосов
/ 07 августа 2010

Другим способом было бы установить максимальное количество символов для URL (скажем, это n). Затем вы можете выбрать случайное число от 1 до n !, которое будет вашим числом перестановок.

На каком новом URL вы увеличиваете идентификатор и используете номер перестановки, чтобы связать фактический идентификатор, который будет использоваться. Наконец, вы должны были бы кодировать ваш URL на основе 32 (или чего-то еще). Это было бы совершенно случайно и совершенно обратимо.

2 голосов
/ 07 августа 2010

Попробуйте Xor'ing $ id с некоторым значением, например $id ^ 46418 - и чтобы преобразовать обратно в исходный идентификатор, просто выполните тот же Xor снова, т.е. $mungedId ^ 46418. Соберите это вместе с base_convert и, возможно, с некоторым обменом символов в результирующей строке, и будет довольно сложно угадать URL.

1 голос
/ 07 августа 2010

Если вы хотите инъективную функцию, вы можете использовать любую форму шифрования. Например:

<?php
$key = "my secret";
$enc = mcrypt_ecb (MCRYPT_3DES, $key, "42", MCRYPT_ENCRYPT);
$f = unpack("H*", $enc);
$value = reset($f);
var_dump($value); //string(16) "1399e6a37a6e9870"

Для реверса:

$rf = pack("H*", $value);
$dec = rtrim(mcrypt_ecb (MCRYPT_3DES, $key, $rf, MCRYPT_DECRYPT), "\x00");
var_dump($dec); //string(2) "42"

Это не даст вам номер в базе 32; он даст вам зашифрованные данные с каждым байтом, преобразованным в основание 16 (то есть преобразование является глобальным). Если вам действительно нужно, вы можете легко преобразовать это в базу 10, а затем в базу 32 с любой библиотекой, которая поддерживает большие целые числа.

0 голосов
/ 17 октября 2016

Hashids - это библиотека с открытым исходным кодом, которая генерирует короткие уникальные непоследовательные идентификаторы, похожие на YouTube из одного или нескольких чисел.Вы можете думать об этом как о алгоритме для запутывания чисел .

. Он преобразует числа типа 347 в строки типа "yr8" или массив типа [27, 986] в "3kTMd".Вы также можете декодировать эти идентификаторы обратно.Это полезно при объединении нескольких параметров в один или просто в качестве коротких идентификаторов UID.

Используйте его, когда вы не хотите, чтобы - выставили вашу базу данных идентификаторы для пользователя.

Позволяет использовать как алфавит, так и соль, поэтому идентификаторы уникальны только для вас.

Инкрементный ввод искажен, чтобы остаться неузнаваемым.

Нет коллизий, потому что метод основан на преобразовании целого числа в шестнадцатеричное.идентификаторы в видимых местах, таких как URL.Следовательно, алгоритм избегает генерации наиболее распространенных английских ругательств.

Пример кода

$hashids = new Hashids();
$id = $hashids->encode(1, 2, 3); // o2fXhV
$numbers = $hashids->decode($id); // [1, 2, 3]
0 голосов
/ 07 августа 2010

Я закончил тем, что создал сумму md5 идентификатора, использовал первые 4 буквенно-цифровых цифры и, если это дубликат, просто увеличивал длину до тех пор, пока он не перестал быть дубликатом.

function idToTinyurl($id) {
    $md5 = md5($id);
    for ($i = 4; $i < strlen($md5); $i++) {
        $possibleTinyurl = substr($md5, 0, $i);
        $res = mysql_query("SELECT id FROM tabke WHERE tinyurl='".$possibleTinyurl."' LIMIT 1");
        if (mysql_num_rows($res) == 0) return $possibleTinyurl;
    }
    return $md5;
}

Принятоответь, так как это приведет меня к этой стратегии.

0 голосов
/ 07 августа 2010

Можно заранее определить 4-значные коды (все возможные комбинации), затем рандомизировать этот список и сохранить его в этом случайном порядке в таблице данных. Если вы хотите новое значение, просто возьмите первое с верха и удалите его из списка. Он быстрый, не требует оперативных вычислений и гарантирует конечному пользователю псевдослучайность.

...