Creating a Random Password Generator Using Python
I am just 5 days in to Dr. Angela Yu’s #100DaysOfCode python course. So far it’s been a great refresher for what I learned to pass Python Institute’s PCEP (Python Entry-Level Programmer) certification. Dr. Yu’s course is way more hands on and practical than the PCEP prep course I took and I highly recommend it for anyone looking to learn Python.
The final project for day 5 is a password generator which allows for practice with importing modules, using for loops, creating and editing lists, and randomization in Python.
In Angela’s example she creates the random password based on the following letters, numbers, and symbols lists and asks for input from the user for how many of each type they want in their password. Then the number of each character type is added to a new list (password_list) and shuffled:
While this works, I thought that this might not fulfill all of the minimum password requirements for many applications. So I decided to edit her random password generator to better fit what I find to be standard password requirements.
The standard requirements I have typically seen are:
- At least one upper case letter
- At least one lower case letter
- At least one symbol
- At least one number
- Password length requirements vary from app to app
It is possible that Angela’s password generator could omit either an uppercase or lowercase letter from the final password, which would not be a valid password for some websites or applications. It also requires the user to determine how many of each character type they want in the password to ensure that the password is at least the minimum required length. Some of my thoughts for how to improve the password generator are as follows:
Instead of asking the user to input how many of each character type they want the password to contain, I’d like the user to be prompted to input the minimum and maximum number of characters their password can be. Different websites/apps have different ranges for password length, so I figured it would be best to allow the user to provide that depending on which website/app they are creating the password for.
I set up the code so that at least one of each character type is included in the final password in order to fulfill the standard password requirements. After the 4 character types are included, the code will fill the rest of the password length with any random character. I thought this would help to randomize the password even further.
Now let’s get to the code.
First, I’ll update the lists so that the upper case and lower case letters are in separate lists.
Then I added a new list that combines all of the character types so that after one of each character type are included the rest of the password length will be populated randomly with any character type.
Then prompt the user for the password length.
Randomly select a password length between the min and max number of characters by setting a new variable.
Create a blank list to generate the password into.
Now that we have the list created, let’s populate the list with the characters of the password. First we’ll account for one random character from each character type.
Then we’ll add in random characters from each type to populate the remainder of the password using a for loop. The code will append a new random character from the all_keys list to the password list until the password list length is equal to the random password_length variable.
Once the for loop is complete, shuffle the password list to randomize it.
Concatenate the individual characters in the password list into a string with the join function. The single quotes before the join function is where to put a delimiter, which is a character to separate the fields in our list. In this case, we don’t want any delimiter because we want our password list to merge into one single password. In other cases, we could add a space or a comma if we wanted our list to print out with a space or character between each item in the list.
Finally, let’s print the password.
Below is an example of the password generator in action. The site we are creating a password for has a min password length of 8 characters and a max of 16. The password comes out to R9ZtKceb*ru#&Vqj which seems like a pretty strong password!
Thanks for reading how I updated Angela Yu’s random password generator. Let me know if you have any thoughts of how to improve it.
Генерация пароля с помощью JavaScript
Наткнулся на интересное решение для генерации случайного пароля с помощью JavaScript. Код очень короткий и простой, он мне настолько понравился, что я решил написать про него небольшую статейку. Расписывать тут особо нечего, вся генерация сводится к одной строке:
Math.random().toString(36).slice(-8);
На этом можно закончить, но получилось совсем короткая запись, даже по меркам twitter`a. Поэтому добавлю пояснение и еще один вариант генерации.
Простая генерация пароля с помощью JavaScript
Для начала попробуем разобраться, как работает эта короткая строка. Первая часть кода Math.random() генерирует случайное число от 0(включительно) до 1(не включительно), то есть создается произвольное число с большим количеством знаков после запятой, например: 0.7642436524728753 . Далее с помощью метода toString(36), полученное длинное число, переводится в строку. Самое интересное, что при переводе можно указывать основание системы счисления, которая будет использоваться при переводе числа. Таким образом, число превращается в набор символов и чисел, получится что-то подобное: 0.rigjv73pl7 . И в конце с помощью метода slice() отрезается нужное количество символов. Если методу передать один отрицательный параметр, то отсчет символов будет с конца.
Когда все стало понятно, также стали очевидны и недостатки кода. Максимальное количество символов, которое может содержать пароль, это 10-11 штук. Также есть очень маленькая, даже практически невозможная, возможность получить ошибку. Ошибка произойдет, когда сгенерируется число 0, без длинного хвоста или когда сгенерируется 0.5 – такой вариант тоже возможен. Но эти недостатки ни сколько не принижают эстетическую красоту кода генерации пароля в одну строку:
Можно оформить код в небольшую функцию, которая будет генерировать пароль с заданым количеством символов:
Второй вариант генерации пароля в JavaScript
Бывает необходимость генерировать пароли длиннее 10 символов, а также иногда необходимо использовать в пароле не только буквы и цифры, а еще и другие случайные символы. Для таких случаев можно воспользоваться этим способом:
Статья Пишем простой генератор сложных паролей
Тема не новая, генераторов существует множество, однако такой простой код и глазу приятен, и место не занимает.
Для начала вставим в шапку кодировку и версию питона. Импортируем модуль random для генерации случайной последовательности. Зададим переменную chars и вобьём буквы в разном регистре, цифры и какие-нибудь спецсимволы для получения максимально взломостойкого пароля.
Вот собственно и всё — простой генератор сложных паролей готов.
Код полностью:
GUI Генератор паролей на Python

Штош. В этой статье я научу вас делать кроссплатформенное приложение генератор паролей с графическим интерфейсом. Мы будем использовать язык Python и библиотеку PySide6 — привязку к инструментарию фреймворка Qt.
Приложение умеет генерировать пароли, скрывать и копировать их в буфер обмена. Длина задается с помощью слайдера и счетчика. Пул допустимых символов меняется кнопками. Сила пароля рассчитывается по информационной энтропии.
В статье я постарался затронуть все моменты создания и сборки приложения. Ознакомиться с проектом можно на GitHub.
Устанавливаем все необходимое
Скачайте и установите Python последней версии (желательно). Приложение должно работать с Python версии 3.7+
Создадим директорию проекта password-generator и виртуальное окружение, в моем случае venvPasswordGenerator
pip install pyside6
Создаем интерфейс
Переходим к созданию интерфейса. Для этого нам понадобится программа Qt Designer. Её можно найти в папке установленной ранее библиотеки.

Окно новой формы в программе Qt Designer
Создаем MainWindow . Убираем menubar и statusbar

Сразу сохраняем файл интерфейса. Я называю его main.ui , потому что в будущем я могу захотеть сделать отдельную форму для настроек или еще чего-то.
Сначала закинем 4 Horizontal Layout для компоновки элементов. Скопировать элемент можно перетаскиванием с зажатой клавишей Ctrl .

Выберем вертикальное расположение для центрального виджета. centralwidget -> Lay Out Vertically

Компоновка выбора символов
Закинем одну кнопку выбора символов в нижнюю горизонтальную компоновку.

Чтобы кнопка имела 2 состояния, нужно поставить свойство checkable

Скопируем кнопку 3 раза. Поставим текст. Я думаю, так должно быть понятно, за какой набор символов отвечает каждая отдельная кнопка.

Дадим элементам осмысленные имена.

Проставим свойство checked на всех символах, кроме специальных.

Компоновка длины пароля
Здесь будет указываться длина пароля с помощью слайдера и счетчика. Компоновку я назову layout_length , слайдер — slider_length , счетчик — spinbox_length

Компоновка энтропии и сложности пароля

Ставим горизонтальное выравнивание по центру.

Копируем элемент и вводим примерный текст.

Компоновка пароля
Перед нами встает интересная задача. Как поместить кнопку видимости пароля в элемент Line Edit? К сожалению, встроенных в Qt Designer методов для такого действия я не нашел. Лучшим решением я посчитал поместить поле и кнопку рядом во фрейме. Если вы знаете способ лучше, поделитесь в комментариях.
Widget Box -> Containers -> Frame

Поставим горизонтальное выравнивание для фрейма.

Добавим 2 кнопки в горизонтальную компоновку, а не во фрейм. Перетаскивать элемент нужно в самый правый край компоновки.

Еще я захотел поставить сверху изображение замка. На удивление, в Qt Designer это тоже реализовано через одно место, в котором никто не хочет побывать. Есть способ с помощью лейбла и его свойства pixmap , но в таком случае нельзя изменять размер изображения. Поэтому я решил сделать через иконку заблокированной кнопки.

Иконки Material Icons
Возьмем иконки для приложения. Я буду использовать бесплатные Material Icons.
Скачаем белую векторную иконку замка. Я выберу первый вид — Outlined. Вы можете взять другой, как вам приятнее.

Для повторной генерации возьмем Refresh. Копирование в буфер обмена — Content Copy. Видимость пароля — Visibility и Visibility Off. Для иконки приложения возьмем черную иконку ключа в формате png и сконвертируем её в формат для иконок ico

Иконки в Windows File Explorer
Создаем файл ресурсов
Создадим файл ресурсов, который будет хранить иконки. Позже мы сконвертируем его в Python код. Resource Browser -> Edit Resources -> New Resource File -> resources.qrc
Добавляем префикс icons

Добавляем все файлы иконок.

Проставляем иконки
В заблокированную кнопку ставим иконку замка с помощью свойства icon -> Disabled On . Выбираем иконку с помощью Choose Resource

Для кнопки видимости выбираем свойство checkable , так как она тоже имеет 2 состояния. Сразу проставим checked по умолчанию.

В Normal Off берем иконку невидимости, в Normal On — видимости.

Остальные иконки проставляем в Normal On

Стилизуем интерфейс
Для стилизации приложения я буду использовать урезанный язык CSS. Писать советую в каком-нибудь редакторе. Я пишу в Visual Studio Code, конечно же.
Главное окно
Создадим файл QMainWindow.css . Для главного виджета поставим цвет фона #121212 , белый цвет текста, шрифт Verdana с размером 16 поинтов и внешний отступ 10 пикселей.
Для кнопок ставим сплошную серую границу 2 пикселя с радиусом границы 5 пикселей.
Вставим код в элемент MainWindow с помощью опции Change styleSheet

Отдельно для кнопок символов я поставлю внутренний отступ 10 пикселей, текст располагается слишком близко к границам.
При наведении на кнопку цвет границ будет меняться на зеленый #090 .
При нажатии граница будет увеличиваться до 4 пикселей.
Для отмеченного состояния кнопки поставим на фон темно-зеленый цвет #006300 .
Чтобы посмотреть превью интерфейса, нужно нажать сочетание клавиш Ctrl + R

Иконка замка
Уберем границы с помощью стиля border: none;
Поставим размер 100 на 100 пикселей.

Фрейм пароля
Поставим для фрейма пароля такую же границу, как и для кнопок. Уберем отступ до правого элемента.
Поставим вертикальную политику Maximum

Поле пароля
Для поля пароля уберем границы и внешние отступы. Поставим размер шрифта 20 поинтов.
Кнопка видимости
Для кнопки видимости пароля так же уберем границы и внешние отступы. Еще поставим прозрачный фон и размер 30 на 30 пикселей.

Кнопка генерации пароля
Для кнопки генерации пароля поставим размер иконки 52 на 52 пикселя. Так границы кнопки будут идти ровно по границам фрейма. Уберем правый и левый внешний отступ.

Кнопка копирования пароля в буфер обмена
Почему-то иконка копирования очень плотно прилегает к границам. Я нашел размер 42 на 42 пикселя и внутренний отступ 5 пикселей. Уберем отступ до левого элемента.

Слайдер
Для псевдоэлемента groove уберем цвет и поставим высоту 5 пикселей. Грув — это линия слайдера, или «желобок», «канавка», «борозда», если верить гугл переводчику.
Слева от ручки слайдера будет зеленый цвет. Для этого используется селектор псевдоэлемента sub-page
Справа от ручки будет серый цвет. Псевдоэлемент add-page
Ручку слайдера я сделаю белой с шириной 22 пикселя, радиусом 10 пикселей и внешними отступами снизу и сверху по -8 пикселей.
Поставим максимум 100 пикселей и значение по умолчанию 12.

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

Лейблы информации
Если растягивать окно интерфейса по вертикали, большую часть будут занимать лейблы информации. Мы этого не хотим, и поэтому ставим у двух лейблов вертикальную политику Maximum

Делаем последние штрихи
Поставим размер приложения по умолчанию. Мне нравится 542 на 418 пикселей. Можете сделать круглые числа, как вам угодно.

Напишем название приложения в свойстве windowTitle . Поставим иконку в windowIcon

Поставим курсор Pointing Hand для кнопок и слайдера.

Уберем демонстрационный текст из лейблов. Он будет генерироваться программой.
Штош. Интерфейс готов, переходим к следующему этапу.

Конвертируем файл ресурсов и интерфейса
Для того, чтобы сконвертировать файл ресурсов, нужно написать в терминал pyside6-rcc , название файла ресурсов, флаг -o и название файла на выходе.
pyside6-rcc resources.qrc -o resources.py
Файл интерфейса конвертируется таким же образом, только с помощью приложения pyside6-uic
pyside6-uic main.ui -o ui_main.py
Этот файл хочет, чтобы я добавлял в конце _rc к файлу ресурсов, а я не хочу. Поменяем import resources_rc на import resources
Пишем код
Рекомендую писать код в среде разработки PyCharm или Visual Studio Code. Vim-еры, не бейте.
Для начала создадим модуль приложения — app.py . Я вставлю готовый сниппет для запуска приложения с файлом дизайна.
Поменяю название класса App на PasswordGenerator
Модуль кнопок
Давайте сделаем отдельный модуль с привязкой сущностей к кнопкам — buttons.py . В стандартной библиотеке string есть строковые переменные для пула символов. Возьмем ascii_lowercase, ascii_uppercase, digits и punctuation.
Вот так они выглядят.
Давайте сделаем перечисление, которое привязывает кнопки выбора символов к этим строковым переменным.
Сразу создадим словарь с количеством символов на каждый пул. Нам это пригодится для расчета энтропии.
Модуль генерации пароля
Давайте сделаем модуль генерации паролей без привязки к интерфейсу — password.py . Напишем функцию создания нового пароля. Аргументами будут длина пароля и все используемые символы в виде строки.
Для генерации безопасного пароля мы будем использовать библиотеку secrets. Сделаем генератор из случайно выбранных символов и соединим их в строку с помощью метода join
Получаем энтропию пароля
Теперь сделаем функцию для получения энтропии. В нее нужно будет передавать длину пароля и количество символов. Формула энтропии пароля выглядит следующим образом:
где N — это количество возможных символов, а L — количество символов в пароле. H измеряется в битах.
Давайте импортируем логарифм по основанию 2 из библиотеки math.
Возвращаем значение, округленное до 2 знаков после запятой.
Перечисление для сложности пароля
Создадим целочисленное перечисление сложности пароля к его энтропии по нижней границе. Я не нашел единого стандарта, в разных генераторах сила пароля считается по-разному, поэтому сделаю так: ничтожный пароль от 0 до 30 бит, слабый после 30, хороший после 50, сильный после 70 и замечательный после 120.
Связываем значения слайдера и счетчика
Давайте сделаем метод класса приложения, который будет связывать значения слайдера и счетчика. Для этого соединим сигнал изменения значения valueChanged с установкой значения другого элемента.
Не забудьте прописать метод в конструкторе класса.
Получаем символы для пароля
Создадим новый метод для получения символов отмеченных кнопок. Объявим пустую строку chars . Для каждой кнопки в перечислении добавляем её символы в строку, если она отмечена.
Ставим пароль
Ну и наконец-то, метод установки пароля. Ставим в элемент line_password новый пароль с помощью метода setText . Длину берем из слайдера или счетчика, не имеет значения.
Добавим метод в конструктор. Приложение должно сгенерировать пароль при запуске.
Соединим изменение слайдера или счетчика с установкой пароля.
Позалипаем на быстрое изменение паролей :3
Когда не нажата ни одна кнопка символов, происходит IndexError . Обработаем этот случай, просто очищая поле пароля.
Получаем количество символов
Принцип тот же, что и у получения строки символов, только в этот раз мы работаем со словарем, а не с перечислением.
Ставим энтропию пароля
Делаем метод для лейбла энтропии. Берем длину из текста пароля, а не из слайдера или счетчика, так нужно. Ставим в лейбл выражение с помощью f-строки.
Добавим установку энтропии в конце метода установки пароля.
Без отмеченных кнопок символов получается ValueError . Обработаем эту ошибку в функции get_entropy модуля password . В таком случае она будет возвращать 0.0.
Ставим сообщение о сложности пароля
Теперь сделаем метод для лейбла сложности пароля. Для каждой сложности из перечисления сравниваем энтропию со значением.
Добавим в конец метода установки пароля.
Ставим генерацию пароля на кнопки
Запишу в модуль buttons кортеж с именами кнопок, при нажатии на которые будет генерироваться новый пароль.
Теперь соединим кнопки с методом в конструкторе класса.
Изменяем видимость пароля
Напишем метод для изменения видимости пароля. Если кнопка отмечена, ставим нормальный эхо мод, иначе ставим эхо мод пароля.
Соединим нажатие кнопки с методом в конструкторе класса.
Копируем в буфер обмена
Чтобы скопировать текст в буфер обмена, нужно вызвать метод clipboard класса QApplication и поставить в него текст.
Так же соединим нажатие кнопки с методом в конструкторе класса. Я думаю, вы справитесь.
Очищаем буфер обмена при закрытии приложения
Для того, чтобы делать что-либо при закрытии приложения, нам нужна функция этого события. В Qt это событие называется QCloseEvent. В PySide6 пишем closeEvent
Событие не нужно ни с чем соединять в конструкторе. Оно работает сразу при объявлении соответствующего метода в классе приложения.
Меняем лейблы при ручном изменении пароля
Остался последний штрих. При ручном изменении пароля энтропия не меняется. Решить проблему можно с помощью сигнала редактирования текста textEdited
Фишка в том, что это будет не совсем правильная энтропия, потому что количество допустимых символов берется по прежнему из отмеченных кнопок. Предлагаю вам самим решить эту проблему.
Меняем структуру проекта
Штош. Давайте поменяем структуру проекта. Поместим все файлы в папку password-generator. Здесь создадим папку ui, в которую поместим все файлы, связанные с интерфейсом. Поменяем импортирование модулей, чтобы все работало. Из ui_main.py я убрал импортирование ресурсов и добавил его в главный модуль приложения.
Создаем файл зависимостей
Создадим файл зависимостей с помощью команды pip freeze > requirements.txt
Система контроля версий
Инициализируем систему контроля версий, конечно же Git. Установите систему, если вы еще этого не сделали. Пропишите в терминал git init из корневого каталога или используйте удобный графический интерфейс в PyCharm.
Создадим файл .gitignore . Будем игнорировать любую папку виртуального окружения, папку PyCharm в моем случае и питонячий кэш. Для VS Code можно прописать .vscode
Теперь можно сделать первый коммит. Опять же, в PyCharm это делается очень удобно, но если вы любите работать в терминале, то пропишите команды:
git commit -m «Initial commit»
Собираем приложение для Windows
Переходим к созданию исполняемых файлов. У Qt есть понятная документация, в которой собраны разные способы дистрибуции приложения. Самый простой способ — это PyInstaller. Нет, вру, самый простой способ — это PyInstaller с интерфейсом, auto-py-to-exe. Все эти библиотеки хороши своей понятностью и легкостью, но обычно на выходе получаются небезопасные и тяжелые бинарники.
Я решил показать вам инструмент получше — компилятор Nuitka. Он доступен для всех версий Qt, работает на всех платформах и распространяется по свободной лицензии MIT.
Установим библиотеку с помощью команды pip install nuitka . Для сборки приложения в один файл понадобится библиотека zstandard , добавим ее в команду через пробел.
Пишем команду компиляции. Собираем приложение в один файл с помощью флага —onefile . Флаг —follow-imports нужен для соблюдения всех импортов. Добавляем плагин PySide6 с помощью флага —enable-plugin=pyside6 . Чтобы убрать консольное окно в системе Windows добавим —windows-disable-console . Добавим иконку с помощью флага —windows-icon-from-ico
Чтобы убрать все генерируемые нуиткой папки сборки добавим флаг —remove-output
Можно указать название файла через флаг -o , но это вообще необязательно, всегда можно просто переименовать файл. В конце напишем путь к файлу скрипта, который мы собираемся собирать.
nuitka —onefile —follow-imports —enable-plugin=pyside6 —windows-disable-console —windows-icon-from-ico=ui\icons\app-icon.ico —remove-output -o password-generator.exe app.py
На выходе получилось приложение с размером 16.7 мегабайт.

Собираем приложение для Linux
Я использовал дистрибутив Ubuntu версии 22.04. С нуиткой вышло громадное приложение в 145 мегабайт. Если вы знаете, как сделать меньше — пишите в комментарии.
python -m nuitka —onefile —follow-imports —enable-plugin=pyside6 —remove-output app.py
Я попробовал собрать приложение с PyInstaller, получилось уже получше, 57,6 мегабайт. С иконкой в докбаре и проводнике вообще беда, она просто не хотела ставиться.
pyinstaller —name=»Password Generator» —windowed app.py
Собираем приложение для macOS
Я использовал версию 10.15 Catalina. Для сборки приложения под macOS нужно прописать специальный параметр —macos-create-app-bundle
python3 -m nuitka —onefile —follow-imports —enable-plugin=pyside6 —macos-create-app-bundle —remove-output -o password-generator.app app.py
Вышло почти так же компактно, как и на винде — 18 мегабайт. С иконкой тоже возникли проблемы, поэтому собирал без нее.
Надеюсь, вам понравился такой комплексный туториал. Генерируйте сильные пароли, дегенерируйте слабые, и будет вам счастье. До встречи.