我正在研究生成随机人类友好代码但不能(轻松)猜测的方法。这将用于赠送奖品(想想独特的折扣代码)。我们要产生大约50k。有没有标准的方法/算法来实现这一目标?我正在考虑使用GUID并应用CRC。这是个坏主意吗?
如果重要,请使用.netframework 3.5。
答案 0 :(得分:6)
我通过从MD5校验和中取出位并将它们用于索引到单词列表中,生成了人性化的校验和。例如:
: nr@yorkie 7012 ; md5words /home/nr/.profile
overextend moonscape cucumbers outsmarting
代码大约有40行Lua,不包括单词列表,它包含在脚本中,以便在每个系统上产生相同的结果。
编辑:
在您的应用程序中,您希望生成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的因素之后,这些数字也对你有利 - 猜测一把钥匙的机会将是千分之一。
更新:2011年8月,此技术成为xkcd cartoon的主题。
答案 1 :(得分:3)
我最喜欢的创造人类友好,可发音,但最终毫无意义和随意的词的方法是马尔可夫链。以下是一些帮助您沿着这条道路前进的链接。
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 - 来自编程珍珠,有一个马尔可夫链生成器的Perl。
http://www.xradiograph.com/WordSalad/ChainsOfLove - 链接到马尔可夫链生成器。
http://www.jwz.org/dadadodo/ - Jamie Zawinski在C中的实施。
请记住,你必须提供这些生成器文本来制作链,然后它会生成单词和句子。
答案 2 :(得分:2)
有些想法让人想到:
如果长度允许,您可以通过从字典中选择单词来生成短语。有关实践中的一个很好的例子,请参阅Diceware。
如果长度更重要,请使用音节列表,结果将是一个无意义但可发音的单词。但是,您可能需要过滤结果以删除不需要的实际单词。
如果不需要可发音,但您希望能够快速验证来自系统的代码,那么(盐渍?)计数器的小CRC会打包到字节数组中并使用{{进行编码3}}或类似的工作。您可以通过保持代码简短来改进人为因素,并选择消除类似字母的编码(即表中没有“O”,“o”,“0”和“Q”)。
如果代码在实践中需要超过大约5个字符,那么请考虑采用标准的标点符号方案将其分解为块。 “A236re8ww1jkm”比“A236-re8wM-1jkz”更难阅读和转录。这里的五号是一个疯狂的猜测...可能有关于最佳长度的文献。
如果这确实是一个加密问题,(即如果伪造这些代码有很大的实际价值),那么请咨询加密专家以获得最佳实践答案,因为滚动自己的问题最终会导致悲伤。 / p>
答案 3 :(得分:2)
Java Pronouncable Passwords是一个生成随机可发音词的网站。源可用,因此您可以将其移植到您需要的任何系统。
这应该为您提供一个可以提供给用户的代码,一个他们有机会记住的代码。
答案 4 :(得分:1)
之前我曾使用Base32来做这类事情。
你只需要一个字母,避免麻烦的字符,如I,L,1,0,O等。
编辑:因此,为了澄清,只需Base32对足够随机生成的字节进行编码即可为您提供所需的字符数。
然后你可能想要将输出分成4组,以获得额外的人类可读性。
编辑2:另一个好主意是将最后一个字母设为校验位 - 即所有先前字节的模数为32的总和。