Человек понятный генератор паролей в JavaScript

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

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);

вывод: "Браунен" (случайная строка)

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

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)

Я нашел другую статью, ссылающуюся на генератор цепей Маркова http://www.soliantconsulting.com/blog/2013/02/draft-title-generator-using-markov-chains в Javascript, но опять же текст генерируется из исходного текста, Возможно ли это без этого и путем определения правил.

2 ответа

Решение

Я думаю, что хорошим подходом может быть использование цепочки Маркова, которая генерируется из большого объема английского текста. Цепь Маркова - это, по сути, вероятностная конструкция, которая зависит от источника, из которого она сгенерирована, поэтому вы, вероятно, получите много английских слов, которые можно произносить. В цепи Маркова у вас есть состояние, из которого вы можете переходить во многие другие состояния в зависимости от вероятности. Поскольку ваша цепочка Маркова будет основана на английских буквах из основного текста на английском языке, переходы от одной буквы к другой будут более вероятными, чем переход к другой. Например, более вероятно, что переход от c в a или же oчем из c в z или же x, У меня есть простой скрипт на Perl, который генерирует цепочки Маркова на основе слов или букв, и я смог получить следующие "слова", которые кажутся вполне произносимыми:

Engulary 
Beavy 
Lan 
Irstatinval
Bassions
Assish 
Forld  
Anturopean 
Cought 
Froot 
Thation 

Имейте в виду, что энтропия ограничена исходным материалом, поэтому лучше иметь большое тело, из которого вы генерируете слова. Взяв указатель из генератора паролей xkcd, упомянутого Diodeus - James MacFarlane, вы можете объединить два или более из этих слов в произносимую, но бессмысленную фразу, которая также может быть паролем.

Простой пример без списка слов (только определенные буквы) для людей с очень хорошей памятью... Чтобы получить понятные человеку слова, нужно добавить больше правил, например, 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;
    }
Другие вопросы по тегам