我正在开发一个脚本,该脚本生成用于密码的人类可口述字符串。我只关心听起来像英语的短语。到目前为止,我已经提出了不同数组的概念:
vowels = ['a','e','i','o','u'];
single_consonants = ['b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'];
double_consonants_leading = ['Bh','Bl','Br','By','Ch','Cl','Cr','Cy','Dr','Dw','Dy','Fl','Fr','Fy','Gh','Gl','Gn','Gr','Gw','Gy','Hy','Jy','Kn','Kr','Kw','Ky','Ly','Mc','Mn','Mr','My','Ny','Ph','Pl','Pn','Pr','Ps','Py','Q','Rh','Ry','Sc','Sh','Sk','Sl','Sm','Sn','Sp','St','Sv','Sw','Sy','Th','Tr','Ts','Tw','Ty','Vr','Vy','Wh','Wr','Wy','Xy','Y','Z'];
double_consonants_trailing = [...'ch'...];
tripple_consonants_leading = [...'Dry','Fly'...];
tripple_consonants_trailing = [...'rch'...];
然后,我将定义一组规则来连接这些数组中的元素以创建字符串,但不一定是在字典中找到的单词。
一个例子是:"节俭纺纱工雪地驱动器"
另一种选择是使用字典中找到的单词列表,但是,我的第一个想法是它是一个有限列表。一旦有人知道您从哪个列表生成字符串,将不可避免地减少破解它所需的时间。
我的解决方案不仅会创建字典中找到的单词,还会创建听起来像单词的字符串。
function generateString(length)
{
.
.
.
return randomString;
}
generateString(7);
输出:"布朗"(随机字符串)
该函数将采用参数长度并返回该长度的字符串,可以通过接受更多参数来改进它,例如要使用的部分数量以及这些部分之间要使用的分隔符。
function generateString(parts,lengthOfPart,separator)
{
.
.
.
return randomString;
}
generateString(4,5,"-");
输出:"Crown-Drive-Knife-Gnome"(4 个字符串,每个字符串长 5 个字符,由连字符分隔)
这就是我目前的情况,这个问题本身是一项正在进行的工作。我想确保我走在正确的轨道上。
我的问题是:这是矫枉过正吗?有什么优点和缺点?最终,我将如何在 JavaScript 中开发它?
编辑 1 (13/11/2013)
此后,我在这里找到了一篇文章:http://www.baekdal.com/insights/password-security-usability 描述了使用常用词列表,但只要在任何给定时间使用三个+单词,那么它就非常安全,因为打破它所需的时间太长了,你试图保护的东西将没有什么价值。
编辑 2 (10:10 14/11/2013)
我找到了另一篇引用 Javascript 中马尔可夫链生成器 http://www.soliantconsulting.com/blog/2013/02/draft-title-generator-using-markov-chains 的文章,但文本再次从源文本生成。没有它并通过定义规则,这可能吗?
我认为一个好的方法可能是使用由大量英语文本生成的马尔可夫链。马尔可夫链基本上是一个概率结构,它依赖于它的来源,所以你可能会得到许多可发音的类似英语的单词。在马尔可夫链中,您有一个状态,您可以从该状态转换到基于概率的许多其他状态。由于您的马尔可夫链将基于英语文本正文中的英文字母,因此从一个字母到另一个字母的过渡比过渡到另一个字母的可能性更大。例如,它更有可能从c
过渡到a
或o
,而不是从c
过渡到z
或x
。我有一个简单的Perl脚本,它基于单词或字母生成马尔可夫链,我能够得到以下似乎非常发音的"单词":
Engulary
Beavy
Lan
Irstatinval
Bassions
Assish
Forld
Anturopean
Cought
Froot
Thation
请记住,熵受源材料的限制,因此最好有一个大主体来生成单词。从Diodeus提到的xkcd密码生成器中获取指针,您可以将其中两个或多个单词组合成可发音但无意义的短语,也可以是密码。
没有单词列表(仅定义字母)的简单示例,适用于记忆力非常好的人......为了获得人类可口语的单词,应该添加更多规则,例如将 4 个元音放在一起。结果
Diecrue - Okeiae - Auasvei
Aovaua - Biaeeo - Suwien
Aiasmea - Aueglou - Koiroa
Doiiui - Domeab - Slokaoa
Oeiuju - Yootraa - Koaeua
Qagwisva - Hiexau - Yovaca
Fleeaee - Peaoui - Xafriaa
Vaaute - Iqovai - Naaaesn
Yauehe - Ueeguu - Mrouiepr
Smikreua - Friusnut - Aoqiji
主代码:http://jsfiddle.net/mMZ3Y/
function get_password_word(n){
var data1 = ['a','e','i','o','u'];
var data2 = ['b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'];
var data3 = ['bl','br','cl','cr','dr','dw','fl','fr','gl','gr','gw','kn','kr','kw','mr','ph','pl','pn','pr','ps','sc','sh','sk','sl','sm','sn','sp','st','sv','sw','tr','ts','wh'];
var str = '';
var last = '';
for(var i = 0; i < n; i++){
var type = getRandomInt(1, 10);
//avoiding some cases
if(last == 3)
type = 1;
if(last == 2)
type = 1;
if(last == 1 && getRandomInt(1, 2) == 1)
type = 2;
//generate
if(type < 4){ //40%
str += data1[getRandomInt(0, data1.length-1)];
last = 1;
}
else if(type < 9){ //40%
str += data2[getRandomInt(0, data2.length-1)];
last = 2;
}
else{ //20%
str += data3[getRandomInt(0, data3.length-1)];
last = 3;
}
}
str = str.charAt(0).toUpperCase() + str.slice(1);
return str;
}