write: 22/02/2024 / modified: 27/09/2024
Парольная фраза — набор грамматически согласованных между собой слов. Слова выбираются случайным образом из специальных словарей.
Первый раз я услышал фразу, наверное, в году 2010 и помню до сих пор — это был пароль администратора VipNet Client: 52 Дровосека Воскрешают Шкаф! Ну что может быть милее случайно сгенерированных, забавных фраз, которые можно использовать в качестве пароля?!
С тех самых пор со мной всегда на флешке VipNet Password Generator
Первые попытки написать подобное на PHP были не очень "забавными". Создал 3 текстовых файла: Описание, Объекты, Действия.
Учитывая то, что в файлах не было единого порядка и отсутствовала хоть какая-то логика в моем скрипте, на выходе получалось не очень.
84 Надкушенных Хинкали Адаптирует Нарубаться 84Yfl{byFlfYfh
96 Параэлектрических Кастрюлечка Придумывает Томить 96GfhRfcGeiNjv
89 Мироедских Водомер Делегирует Вогнутость 89VbhDjlLtkDju
62 Липких Мирцен Мариновали Интеллектуальность 62KbgVbhVthByn
29 Яхонтовых Гиппопотам Выдумывает Укручиваться 29Z[jUbgDslErh
Да и еще, как оказалось, пхп не умеет склонять русские слова. Какой позор.
Срочно нужен был склонятор
, у яндекса когда-то был такой, работал через API. Но проект прикрыли как и все проекты яндекс.нано (вроде так они назывались).
Нашел Генератор синтаксически правильного русского текста Geniot.
Ты, могучая смерть, генерируемая средствами религий, дезавуируешь трактиры смерти подвыпившие.
Милота же (: Но попытавшись разобраться в логике я сжег пару стульев под собой, автору респект, но мне нужно что нибудь попроще.
Постепенно погружаясь в основы русского языка, было принято решение идти по такому пути:
Предложение в английском языке может состоять из следующих членов: подлежащего (subject), сказуемого (predicate), дополнения (object или complement), обстоятельства (adverbial modifier) и определения (attribute):
Подлежащее — это лицо или предмет, выполняющий какое-либо действие. Это главный член предложения, субъект, о котором в предложении что-то говорится. Подлежащее отвечает на вопросы: "Кто?", "Что?"
Сказуемое — (предикат) в английском языке выражает действие, совершаемое подлежащим, или же описывает его состояние. Основой сказуемого всегда является смысловой, модальный или вспомогательный глагол.
Создаю базу SQLite с 4 таблицами: Object, Subject, Predicate и Attrubute.
Пример таблицы Subject.
Слово | падеж | Род | Число |
---|---|---|---|
маникюрш | Винительный падеж | женский | множественное |
сторож | Именительный падеж | мужской | единственное |
террориста | Винительный падеж | мужской | единственное |
дровосеков | Винительный падеж | мужской | множественное |
Ну и на выходе, если брать в пример фразу из 5 слов, по логике, должно будет получаться, что-то типа этого:
36
Взбалмошных
— Attribute: Винительный падеж, множ. число (Какого? Чьего?)
Маникюрш
— Subject: Винительный падеж, женский род, множ. число (Кого? Что?)
Шлифуют
— Predicate: Настоящее время, Что делают/сделали?
Волосатого
— Attribute: Винительный падеж, мужской род, ед.число (Какого? Чьего?)
Бандерлога
— Object: Винительный падеж, ед.число (Кого? Что?) !31
Непредсказуемая
— Attribute: Именительный падеж, женский род, ед.число (Какой? Чей?)
Маникюрша
— Subject: Именительный падеж, женский род, ед.число (Кто? Что?)
Шлифовала
— Predicate: Прошедшее время, Что делают/сделали?
Незыблемого
— Attribute: Винительный падеж, мужской род, ед.число (Какого? Чьего?)
Консьержа
— Object: Винительный падеж, мужской род, ед.число (Кого? Что?) !
Осталось дело за малым, сделать базу и заполнить ее словами в разных склонениях, а так-же всеми параметрами: род, число, время, падеж и т.д. Файлы с базами випнета (attrib.rus, object.rus, subject.rus и predicat.rus) оказались в непонятном для меня формате, поэтому их позаимствовать у меня не вышло. Буду признателен за подсказку. Как вариант, нагенерировать кучу фраз, вычленить слова и ручками распихать по таблицам. Но решил не заморачиваться. Для пущей боли был найден самый большой словарь на 2 376 435 слов и словарь с склонениями.
И все равно, с русским языком у меня отношения натянутые, поэтому временами приходится обращаться за помощью к жене или Морфею.
На коленке был написан скрипт, выбирающий случайным образом слово из файла и предлагающий выбрать для него нужные параметры в зависимости от того в какую таблицу нужно добавить слово. После добавления в таблицу слово из файла удаляется и предлагается новое.
Убивалка времени в маршрутках готова.
Для реализации нескольких форм на одной странице использовал табы с jQuery:
<script>
$( function() {
$( "#tabs" ).tabs();
} );
</script>
<div id="tabs">
<ul>
<li><a href="#tabs-1">Аттрибут</a></li>
<li><a href="#tabs-2">Объект</a></li>
<li><a href="#tabs-3">Предикатив</a></li>
<li><a href="#tabs-4">Субъект</a></li>
</ul>
Чтобы обработчик не путался какую именно я отправляю форму добавил <input type="hidden" name="form" value="attribute">
, и тут же в скрипте принимаю метод $_POST в зависимости от формы:
if(isset($_POST['form'])){
switch ($_POST['form']) {
case "attribute":
echo "Отправлена форма Attribute";
break;
case "object":
echo "Отправлена форма Object";
break;
case "predicate":
echo "Отправлена форма Predicate";
break;
case "subject":
echo "Отправлена форма Subject";
break;
default:
echo "O_o ?";
}
}
Мое любимое выражение на все времена: Героическое преодоление никому не нужных проблем.
В итоге я понял, что перебирая 2 млн слов вручную можно свихнуться и напрочь потерять интерес к всяким там дяйвай. Протерев глаза и по новой обратившись к гуглу, были найдены Морфологические словари русского языка в виде SQL скриптов.
Конкретно меня выручили 3 словаря:
— База прилагательных — 856,128 словоформ. Склонения по родам, падежам, ед/мн число.
— База существительных — 767,694 словоформ, в том числе во множественном числе.
— База глаголов — 467,722 словоформ. Склонения по лицам, временам, родам, числам.
Если от ненужных падежей и столбцов можно было быстро избавиться запросами, то вот от неинтересных и ненужных слов я избавлялся наверное неделю. В итоге в моей базе SQLite получилось следующее: таблица Attribute 20828 слов, таблица Subject 9905 слов, таблица Object 3676 слов и таблица Predicate (действий) 10935 слов.
Ну чтож, нужно начинать с цифр. Помогло нагугленное решение, что-то типа этого:
function declOfNum($num, $titles) {
$cases = array(2, 0, 1, 1, 1, 2);
return $num . " " . $titles[($num % 100 > 4 && $num % 100 < 20) ? 2 : $cases[min($num % 10, 5)]];
}
echo declOfNum(5, array('человек просит', 'человека просят', 'человек просят'));
Генерируем случайное число, определяем единственное или множественное, из базы берем субъект с нужным типом, берем для субъекта случайное описание с нужным полом и числом, выбираем действие (прошлое или настоящее время), берем объект который будет совершать действие над субъектом и выбираем для него описание.
В процессе мне стало скучно, а точнее я начал тупить и чтобы хоть как-то отвлечься и развлечь себя, решил внести разнообразия, добавил в базу таблицу Emoji
, импортировал в нее около 4 тысяч записей, из которых оставил лишь 1945, почистив от так называемых толерантных эмодзи.
Теперь при генерации парольной фразы также генерируется визуальная история из эмодзи равной количеству слов в фразе. 🪄🧂😑🥼👩🏻🎓
Для транслитерации слов воспользовался готовым решением, лишь изменив транслит на QWERTY раскладку. Первые буквы каждого слова перевожу в заглавные, вырезаю из каждого слова первые символы исходя из запроса и объединяю в пароль. Тад-а-а-м!
Прикрутил отправку запросов через jQuery.ajax, и добавил две функции определения энтропии полученного пароля по NIST и Wolfram:
Национальный институт стандартов и технологий (США) (NIST) для оценки энтропии пароля, созданного человеком и не включающего символы из неанглийских алфавитов, предлагает использовать следующий алгоритм:
4
битам;2
бита на каждый символ;1.5
бита на каждый символ;1
биту на каждый символ;6
бит.function entropyNist($pass) {
$entropy=0;
$strlenght=strlen($pass);
if ($strlenght > 0) { $entropy += 4; }
if ($strlenght > 1) { $entropy += 2*min($strlenght-1,7); }
if ($strlenght > 8) { $entropy += 1.5*min($strlenght-8,12); }
if ($strlenght > 20) { $entropy += 1*($strlenght-20); }
if (preg_match('/[A-Z]/',$pass)
&& preg_match('/[a-z]/',$pass)
&& preg_match('/[^a-zA-Z]/',$pass)) { $entropy += 6; }
return $entropy;
}
У Wolfram Alpha более щепетильный тест энтропии.
В генераторе можно выбрать количество слов в фразе (от 3 до 5 слов), количество цифр перед фразой (от 2 до 4 цифр), количество букв от каждого слова для создания пароля (от 2 до 4 букв) и опция верхнего регистра первой буквы для каждого слова.
--
Выбор верхнего регистра от 1 до 4 символов в зависимости от количества букв слова
Рандомные спецсимволы междуобрезками
слов для пароля
--
russian.dic — Словарь 2376435 слов
vseoDiction_ru.txt — Словарь 2375330 слов
russian.txt — Словарь 1532630 слов
nouns.csv — Словарь 26982 слова с разными склонениями
Сервис спряжения и склонения слов PROMT.One
Морфологический разбор слов morphologyonline.ru
tags: php programming javascript sqlite web