Статическое тестирование кода
This commit is contained in:
178
lab3/programm/passgen.py
Normal file
178
lab3/programm/passgen.py
Normal file
@@ -0,0 +1,178 @@
|
||||
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):
|
||||
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():
|
||||
"""Запрашивает у пользователя параметры генерации пароля с проверкой ввода."""
|
||||
global max_password_length
|
||||
|
||||
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 (use_lower or use_upper or use_digits or use_special):
|
||||
print("Ошибка: необходимо выбрать хотя бы один тип символов.")
|
||||
return get_user_input() # Повторный ввод всех данных
|
||||
|
||||
# Запрашиваем минимальное количество каждого типа символов
|
||||
min_lower = (
|
||||
get_valid_int("Минимальное количество строчных букв: ", 0) if use_lower else 0
|
||||
)
|
||||
min_upper = (
|
||||
get_valid_int("Минимальное количество заглавных букв: ", 0) if use_upper else 0
|
||||
)
|
||||
min_digits = get_valid_int("Минимальное количество цифр: ", 0) if use_digits else 0
|
||||
min_special = (
|
||||
get_valid_int("Минимальное количество спецсимволов: ", 0) if use_special else 0
|
||||
)
|
||||
|
||||
return (
|
||||
length,
|
||||
use_lower,
|
||||
use_upper,
|
||||
use_digits,
|
||||
use_special,
|
||||
min_lower,
|
||||
min_upper,
|
||||
min_digits,
|
||||
min_special,
|
||||
)
|
||||
|
||||
|
||||
def validate_input(length, min_lower, min_upper, min_digits, min_special):
|
||||
"""Проверяет, что длина пароля больше суммы минимальных значений."""
|
||||
total_required = min_lower + min_upper + min_digits + min_special
|
||||
if total_required > length:
|
||||
print(
|
||||
f"Ошибка: сумма минимальных значений ({total_required}) превышает длину пароля ({length})."
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def generate_mandatory_chars(
|
||||
min_lower,
|
||||
min_upper,
|
||||
min_digits,
|
||||
min_special,
|
||||
lower_chars,
|
||||
upper_chars,
|
||||
digit_chars,
|
||||
special_chars,
|
||||
):
|
||||
"""Генерирует обязательные символы пароля."""
|
||||
password = (
|
||||
random.choices(lower_chars, k=min_lower)
|
||||
+ random.choices(upper_chars, k=min_upper)
|
||||
+ random.choices(digit_chars, k=min_digits)
|
||||
+ random.choices(special_chars, k=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(
|
||||
length,
|
||||
use_lower,
|
||||
use_upper,
|
||||
use_digits,
|
||||
use_special,
|
||||
min_lower,
|
||||
min_upper,
|
||||
min_digits,
|
||||
min_special,
|
||||
):
|
||||
"""Генерирует пароль с учётом заданных параметров."""
|
||||
lower_chars = string.ascii_lowercase if use_lower else ""
|
||||
upper_chars = string.ascii_uppercase if use_upper else ""
|
||||
digit_chars = string.digits if use_digits else ""
|
||||
special_chars = "!@#$%^&*" if use_special else ""
|
||||
|
||||
all_chars = lower_chars + upper_chars + digit_chars + special_chars
|
||||
|
||||
while not validate_input(length, min_lower, min_upper, min_digits, min_special):
|
||||
print("Пожалуйста, введите параметры заново.")
|
||||
return generate_password(*get_user_input())
|
||||
|
||||
password = generate_mandatory_chars(
|
||||
min_lower,
|
||||
min_upper,
|
||||
min_digits,
|
||||
min_special,
|
||||
lower_chars,
|
||||
upper_chars,
|
||||
digit_chars,
|
||||
special_chars,
|
||||
)
|
||||
password = fill_password(password, length, all_chars)
|
||||
password = shuffle_password(password)
|
||||
|
||||
return password
|
||||
|
||||
|
||||
def main():
|
||||
"""Основная функция программы."""
|
||||
max_password_length = 100
|
||||
user_data = get_user_input()
|
||||
password = generate_password(*user_data)
|
||||
print("Сгенерированный пароль:", password)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
173
lab3/programm/passgen_refactor.py
Normal file
173
lab3/programm/passgen_refactor.py
Normal file
@@ -0,0 +1,173 @@
|
||||
"""
|
||||
Модуль для генерации безопасных паролей с разными настройками.
|
||||
Пользователь может задавать длину, типы символов и минимальное количество каждого типа.
|
||||
"""
|
||||
|
||||
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()
|
||||
Reference in New Issue
Block a user