Человек понятный генератор паролей в 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;
}