Files
software-testing/lab3/programm/passgen_refactor.py

174 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Модуль для генерации безопасных паролей с разными настройками.
Пользователь может задавать длину, типы символов и минимальное количество каждого типа.
"""
import random
import string
MAX_PASSWORD_LENGTH = 100 # Максимальная длина пароля
def get_valid_int(prompt, min_value=0, max_value=None):
"""Запрашивает у пользователя целое число, проверяя корректность ввода."""
while True:
user_input = input(prompt).strip()
if not user_input:
print("Ошибка: ввод не должен быть пустым. Попробуйте снова.")
continue
try:
value = int(user_input)
if value < min_value:
print(
f"Ошибка: значение должно быть не меньше {min_value}. Попробуйте снова."
)
continue
if max_value and value > max_value:
print(
f"Ошибка: значение должно быть не больше {max_value}. Попробуйте снова."
)
continue
return value
except ValueError:
print("Ошибка: введите корректное целое число.")
def get_yes_no(prompt):
"""Запрашивает у пользователя 'yes'/'y' или 'no'/'n', проверяя корректность ввода."""
while True:
user_input = input(prompt).strip().lower()
if user_input in ["yes", "y"]:
return True
if user_input in ["no", "n"]:
return False
print("Ошибка: введите 'yes' (или 'y') или 'no' (или 'n').")
def get_user_input():
"""Запрашивает у пользователя параметры генерации пароля с проверкой ввода."""
settings = {
"length": get_valid_int(
f"Введите длину пароля (1-{MAX_PASSWORD_LENGTH}): ",
min_value=1,
max_value=MAX_PASSWORD_LENGTH,
),
"use_lower": get_yes_no("Использовать строчные буквы? (yes/y, no/n): "),
"use_upper": get_yes_no("Использовать заглавные буквы? (yes/y, no/n): "),
"use_digits": get_yes_no("Использовать цифры? (yes/y, no/n): "),
"use_special": get_yes_no(
"Использовать спецсимволы (!@#$%^&*)? (yes/y, no/n): "
),
}
# Проверяем, что хотя бы один тип символов выбран
if not any(
[
settings["use_lower"],
settings["use_upper"],
settings["use_digits"],
settings["use_special"],
]
):
print("Ошибка: необходимо выбрать хотя бы один тип символов.")
return get_user_input() # Повторный ввод всех данных
# Запрашиваем минимальное количество каждого типа символов
settings["min_lower"] = (
get_valid_int("Минимальное количество строчных букв: ", 0)
if settings["use_lower"]
else 0
)
settings["min_upper"] = (
get_valid_int("Минимальное количество заглавных букв: ", 0)
if settings["use_upper"]
else 0
)
settings["min_digits"] = (
get_valid_int("Минимальное количество цифр: ", 0)
if settings["use_digits"]
else 0
)
settings["min_special"] = (
get_valid_int("Минимальное количество спецсимволов: ", 0)
if settings["use_special"]
else 0
)
return settings
def validate_input(settings):
"""Проверяет, что длина пароля больше суммы минимальных значений."""
total_required = sum(
[
settings["min_lower"],
settings["min_upper"],
settings["min_digits"],
settings["min_special"],
]
)
if total_required > settings["length"]:
print(
f"Ошибка: сумма минимальных значений ({total_required})"
f" превышает длину пароля ({settings['length']})."
)
return False
return True
def generate_mandatory_chars(settings, char_sets):
"""Генерирует обязательные символы пароля."""
password = (
random.choices(char_sets["lower"], k=settings["min_lower"])
+ random.choices(char_sets["upper"], k=settings["min_upper"])
+ random.choices(char_sets["digits"], k=settings["min_digits"])
+ random.choices(char_sets["special"], k=settings["min_special"])
)
return password
def fill_password(password, length, all_chars):
"""Дополняет пароль случайными символами до нужной длины."""
remaining_length = length - len(password)
password += random.choices(all_chars, k=remaining_length)
return password
def shuffle_password(password):
"""Перемешивает символы пароля случайным образом."""
random.shuffle(password)
return "".join(password)
def generate_password(settings):
"""Генерирует пароль с учётом заданных параметров."""
char_sets = {
"lower": string.ascii_lowercase if settings["use_lower"] else "",
"upper": string.ascii_uppercase if settings["use_upper"] else "",
"digits": string.digits if settings["use_digits"] else "",
"special": "!@#$%^&*" if settings["use_special"] else "",
}
all_chars = "".join(char_sets.values())
while not validate_input(settings):
print("Пожалуйста, введите параметры заново.")
return generate_password(get_user_input())
password = generate_mandatory_chars(settings, char_sets)
password = fill_password(password, settings["length"], all_chars)
password = shuffle_password(password)
return password
def main():
"""Основная функция программы."""
user_settings = get_user_input()
password = generate_password(user_settings)
print("Сгенерированный пароль:", password)
if __name__ == "__main__":
main()