Генерация удобных для пользователя кодов - PullRequest
3 голосов
/ 25 марта 2009

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

Использование .netframework 3.5, если это имеет значение.

Ответы [ 5 ]

6 голосов
/ 25 марта 2009

Я сгенерировал удобные для человека контрольные суммы, взяв биты из контрольной суммы MD5 и используя их в качестве индекса в списке слов. Например:

: nr@yorkie 7012 ; md5words /home/nr/.profile  
overextend moonscape cucumbers outsmarting

Код - это около 40 строк Lua, не считая списка слов, который включен в скрипт для получения идентичных результатов в каждой системе.


EDIT:

В вашем приложении вы хотите сгенерировать 50 000 ключей. Вы можете сделать это примерно так:

for ((i=1; i<=50000; i++))
do 
  echo "this is my secret phrase $i" | md5words
done

Использование этой процедуры с другой секретной фразой дает следующие ключи:

Chisinau Phaethon customs Martina
commensurate freewill logical cambered
kamikazes Creighton Dobro's Alonzo
medallion's jesters goofy keystones
Anaxagoras martial Medina's Hon's
acclimatized chirping Cleopatra's mascaras
buoyant nuclear lumbering disagreements
dampens Philby cloak drollness

Эти ключи трудно подделать: список слов содержит почти 100 000 слов, поэтому имеется 10 ^ 20 возможных последовательностей из 4 слов. Если у вас есть 100 000 кодов, вероятность того, что кто-то сможет угадать код в случайном порядке, составляет один из 10 ^ 15. Если вы поставите газ на количество клавиш, которые разрешено использовать, скажем, одну клавишу каждые 0,3 секунды, у вас не возникнет проблем.

Если бы я развертывал эту идею в вашем приложении, я бы сократил список слов до чего-то более короткого, возможно, только до 10 000 слов, которые очень широко известны. Даже после потери коэффициента 10 ^ 4 цифры оказываются в вашу пользу - вероятность угадать ключ будет 1 на 100 млрд.


ОБНОВЛЕНИЕ : В августе 2011 года эта техника была предметом xkcd карикатуры .

3 голосов
/ 25 марта 2009

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

http://www.codinghorror.com/blog/archives/001132.html - Объяснение Джеффа Этвуда (очень хорошо!)

http://en.wikipedia.org/wiki/Markov_chain - Википедия о цепях Маркова длинна и идет по математике.

http://www.cs.bell -labs.com / cm / cs / pearls / sec153.html - В программе Programming Pearls имеется Perl для генератора цепей Маркова.

http://www.xradiograph.com/WordSalad/ChainsOfLove - Имеет ссылки на цепные генераторы Маркова.

http://www.jwz.org/dadadodo/ - реализация Джейми Завински в C.

И помните, что вы должны кормить эти генераторы текста, чтобы создать цепочки, тогда он будет генерировать из них слова и предложения.

2 голосов
/ 25 марта 2009

Произносимые пароли Java - это сайт, который генерирует случайные произносимые слова. Источник доступен, так что вы можете перенести его на любую систему, которая вам нужна.

Это должно предоставить вам код, который вы можете дать пользователю, который он действительно может запомнить.

2 голосов
/ 25 марта 2009

Несколько идей, которые приходят на ум:

  • Если позволяет длина, вы всегда можете генерировать фразы, выбирая слова из словаря. Хороший пример этого на практике см. Diceware .

  • Если длина более важна, используйте список слогов, и результатом будет бессмысленное, но произносимое слово. Однако может потребоваться отфильтровать результаты, чтобы удалить нежелательные фактические слова.

  • Если произнесение не требуется, но вы хотите иметь возможность быстро проверить код, поступающий из вашей системы, тогда небольшой CRC счетчика (подсоленного?) Упакован в байтовый массив и закодирован с помощью base64 или аналогичный будет работать. Вы можете улучшить человеческий фактор, оставив код коротким и выбрав кодировку, которая исключает подобные буквы (т. Е. В таблице нет «O», «o», «0» и «Q»).

  • Если на практике код должен быть длиннее примерно 5 символов, подумайте о принятии стандартной схемы пунктуации, которая разбивает его на куски. «A236re8ww1jkm» намного сложнее, чем «A236-re8wM-1jkz», чтобы читать и транскрибировать. Число пять здесь - дикое предположение ... вероятно, есть литература на лучшую длину.

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

1 голос
/ 25 марта 2009

Я использовал Base32 раньше для такого рода вещей.

Вам просто нужен алфавит, который позволяет избежать неприятных символов, таких как I, L, 1, 0, O и т. Д.

Редактировать : Итак, чтобы уточнить, просто Base32 кодирует достаточно случайно сгенерированных байтов, чтобы дать вам необходимое количество символов.

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

Редактировать 2: Еще одна хорошая идея - сделать последнюю букву контрольной цифрой - скажем, сумму всех предыдущих байтов по модулю 32.

...