4

我正在开发一个脚本,该脚本会生成用于密码的人类可说的字符串。我只关心听起来像英语的短语。到目前为止,我已经提出了不同数组的概念:

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'...];

然后,我将定义一组规则来连接这些数组中的元素以创建字符串,但不一定是您可以在字典中找到的单词。

一个例子是:“ Frug-Spunner-Snow-Drive

另一种选择是使用在字典中找到的单词列表,但是,我首先想到的是它是一个有限列表。一旦有人知道您从哪个列表生成字符串,将不可避免地减少破解它所需的时间。

我的解决方案不仅会创建在字典中找到的单词,还会创建听起来像单词的字符串。

function generateString(length)
{
.
.
.
return randomString;
}

generateString(7);

输出: “Brownen”(随机字符串)

该函数将接受一个参数长度并返回一个该长度的字符串,可以通过接受更多参数来改进它,例如要使用多少部分以及这些部分之间要使用的分隔符

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的文章,但同样是从源文本生成的文本. 如果没有它并通过定义规则,这是否可能。

4

2 回答 2

4

我认为一个好的方法可能是使用从大量英文文本生成的马尔可夫链。马尔可夫链基本上是一种概率构造,它取决于生成它的来源,因此您可能会得到许多可发音的类似英语的单词。在马尔可夫链中,您有一个状态,您可以根据概率从该状态转换到许多其他状态。由于您的马尔可夫链将基于英文文本正文中的英文字母,因此从一个字母到另一个字母的转换比到另一个字母的转换更有可能。例如,它更有可能从cao,而不是从czx。我有一个简单的 Perl 脚本它根据单词或字母生成马尔可夫链,我能够得到以下看起来非常发音的“单词”:

Engulary 
Beavy 
Lan 
Irstatinval
Bassions
Assish 
Forld  
Anturopean 
Cought 
Froot 
Thation 

请记住,尽管熵受源材料的限制,所以最好有一个大的主体来生成单词。从Diodeus提到的xkcd 密码生成器中获取指针,您可以将这些单词中的两个或多个组合成可发音但无意义的短语,也可以是密码。

于 2013-11-13T23:26:32.357 回答
0

没有单词列表(仅定义字母)的简单示例,适用于记忆力非常好的人......为了获得人类会说的单词,应该添加更多规则,例如 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;
    }
于 2013-11-14T11:18:37.653 回答