Как я могу создать уникальный, маленький, случайный и удобный ключ? - PullRequest
13 голосов
/ 29 августа 2008

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

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

Af3nT5Xf2

К сожалению, я никогда не был доволен реализацией. О гидах не могло быть и речи, они были просто слишком большими и трудными для ввода пользователями. Я надеялся на что-то более похожее на 4 или 5 символов / цифр, но наша конкретная реализация будет генерировать заметно паттерны последовательностей, если мы закодируем в менее 9 символов.

Вот что мы в итоге сделали:

Мы извлекли уникальный последовательный 32-битный идентификатор из базы данных. Затем мы вставили его в центральные биты 64-битного случайного числа. Мы создали таблицу поиска легко набираемых и распознаваемых символов (A-Z, a-z, 2-9, пропуская легко перепутанные символы, такие как L, l, 1, O, 0 и т. Д.). Наконец, мы использовали эту таблицу поиска для кодирования base-54 64-разрядного целого числа. Старшие биты были случайными, младшие биты были случайными, но центральные биты были последовательными.

Конечным результатом был код, который был намного меньше, чем guid, и выглядел случайным, даже если это абсолютно не так.

Я никогда не был удовлетворен этой конкретной реализацией. Что бы вы, ребята, сделали?

Ответы [ 5 ]

7 голосов
/ 29 августа 2008

Вот как бы я это сделал.

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

Тогда я бы запустил фильтр, чтобы неясные слова были удалены, а слишком длинные слова исключены.

Тогда мой алгоритм генерации выберет 2 слова из списка, объединит их и добавит случайное трехзначное число.

Я также могу рандомизировать шаблон выбора слов между глаголами / существительными, например

eatCake778
pickBasket524
rideFlyer113 и т.д ..

случай не должен быть верблюжьей, вы можете также рандомизировать это. Вы также можете рандомизировать расположение числа и глагола / существительного.

И так как это очень много рандомизирует, Джеффа Опасность наивности необходимо прочитать. Также обязательно заранее изучите атаки по словарю.

И после того, как я это реализовал, я запустил тест, чтобы убедиться, что мои алгоритмы никогда не сталкиваются. Если бы частота столкновений была высокой, то я бы поиграл с параметрами (количество использованных существительных, количество используемых глаголов, длина случайного числа, общее количество слов, различные виды оболочек и т. Д.)

3 голосов
/ 29 августа 2008

В .NET вы можете использовать метод GetBytes () RNGCryptoServiceProvider, который «заполнит массив байтов криптографически сильной последовательностью случайных значений» (из документации ms).

byte[] randomBytes = new byte[4];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);

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

3 голосов
/ 29 августа 2008

В C # я использовал метод ' System.IO.Path.GetRandomFileName (): String ' ... но я генерировал соль для имен файлов отладки. Этот метод возвращает материал, похожий на ваш первый пример, за исключением случайного расширения файла .xyz.

Если вы находитесь в .NET и хотите просто более простое (но не «красивое») решение, я бы сказал, что вот оно ... вы можете удалить случайное расширение файла, если хотите.

0 голосов
/ 29 августа 2008

Вы можете загрузить свой список слов, предложенный чакритом, в таблицу данных или XML-файл с уникальным последовательным ключом. Получая ваше случайное слово, используйте генератор случайных чисел, чтобы определить, какие слова выбрать по их ключу. Если вы объедините 2 из них, я не думаю, что вам нужно включать числа в строку, если только «истинная случайность» не является частью цели.

0 голосов
/ 29 августа 2008

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

Если вы ищете способ кодирования случайного кода в строке URL, и это проблема, с которой я сталкивался некоторое время, то я использовал 64-битные кодированные GUID.

...