tuduf.ruhobbytech.itweb › phrase.gen

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) для оценки энтропии пароля, созданного человеком и не включающего символы из неанглийских алфавитов, предлагает использовать следующий алгоритм:

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