| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731 |
- import tkinter as tk
- from tkinter import messagebox, scrolledtext, ttk
- import string
- import random
- import sqlite3
- from datetime import datetime
- import json
- import os
- class PasswordGenerator:
- def __init__(self):
- self.root = tk.Tk()
- self.root.title("Генератор надежных паролей PRO")
- self.root.geometry("750x700")
-
- # Инициализация базы данных ДО создания интерфейса
- self.init_database()
-
- self.setup_ui()
-
- # Переменные для настроек
- self.current_password = ""
- self.history_limit = 15
- self.config_file = "config.json"
- self.load_config()
-
- def setup_ui(self):
- # Создание стилей
- style = ttk.Style()
- style.configure('Custom.TButton', font=('Arial', 10, 'bold'))
- style.configure('Title.TLabel', font=('Arial', 16, 'bold'))
-
- # Главный контейнер
- main_frame = ttk.Frame(self.root, padding="20")
- main_frame.pack(fill=tk.BOTH, expand=True)
-
- # Заголовок
- title_label = ttk.Label(main_frame, text="🔐 ГЕНЕРАТОР НАДЕЖНЫХ ПАРОЛЕЙ",
- style='Title.TLabel')
- title_label.pack(pady=(0, 20))
-
- # Фрейм настроек
- settings_frame = ttk.LabelFrame(main_frame, text="Настройки генерации", padding="15")
- settings_frame.pack(fill=tk.X, pady=(0, 15))
-
- # Длина пароля
- length_frame = ttk.Frame(settings_frame)
- length_frame.pack(fill=tk.X, pady=5)
-
- self.length_label = ttk.Label(length_frame, text="Длина пароля:", width=15)
- self.length_label.pack(side=tk.LEFT)
-
- self.length_var = tk.IntVar(value=16)
- self.length_slider = ttk.Scale(length_frame, from_=8, to=32,
- variable=self.length_var, orient=tk.HORIZONTAL)
- self.length_slider.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=10)
-
- self.length_display = ttk.Label(length_frame, textvariable=self.length_var, width=3)
- self.length_display.pack(side=tk.LEFT)
-
- # Чекбоксы для символов
- self.letters_var = tk.BooleanVar(value=True)
- self.digits_var = tk.BooleanVar(value=True)
- self.punctuation_var = tk.BooleanVar(value=True)
- self.exclude_similar = tk.BooleanVar(value=True)
- self.exclude_ambiguous = tk.BooleanVar(value=False)
-
- checks_frame = ttk.Frame(settings_frame)
- checks_frame.pack(fill=tk.X, pady=10)
-
- ttk.Checkbutton(checks_frame, text="Буквы (A-Z, a-z)",
- variable=self.letters_var).pack(side=tk.LEFT, padx=10)
- ttk.Checkbutton(checks_frame, text="Цифры (0-9)",
- variable=self.digits_var).pack(side=tk.LEFT, padx=10)
- ttk.Checkbutton(checks_frame, text="Спецсимволы (!@#$%)",
- variable=self.punctuation_var).pack(side=tk.LEFT, padx=10)
-
- advanced_frame = ttk.Frame(settings_frame)
- advanced_frame.pack(fill=tk.X, pady=5)
-
- ttk.Checkbutton(advanced_frame, text="Исключить похожие символы (i, l, 1, L, o, 0, O)",
- variable=self.exclude_similar).pack(side=tk.LEFT, padx=10)
- ttk.Checkbutton(advanced_frame, text="Исключить неоднозначные символы ({[]}<>\\|)",
- variable=self.exclude_ambiguous).pack(side=tk.LEFT, padx=10)
-
- # Кнопка генерации
- self.generate_btn = ttk.Button(main_frame, text="⚡ СГЕНЕРИРОВАТЬ ПАРОЛЬ",
- command=self.generate_password,
- style='Custom.TButton')
- self.generate_btn.pack(pady=10)
-
- # Отображение пароля
- result_frame = ttk.LabelFrame(main_frame, text="Сгенерированный пароль", padding="15")
- result_frame.pack(fill=tk.X, pady=(0, 15))
-
- self.password_var = tk.StringVar()
- self.password_entry = ttk.Entry(result_frame, textvariable=self.password_var,
- font=('Courier', 14), justify='center')
- self.password_entry.pack(fill=tk.X)
-
- # Кнопки действий с паролем
- action_frame = ttk.Frame(main_frame)
- action_frame.pack(pady=(0, 15))
-
- ttk.Button(action_frame, text="📋 Копировать",
- command=self.copy_to_clipboard).pack(side=tk.LEFT, padx=5)
- ttk.Button(action_frame, text="💾 Сохранить",
- command=self.save_password).pack(side=tk.LEFT, padx=5)
- ttk.Button(action_frame, text="🔄 Новый",
- command=self.generate_password).pack(side=tk.LEFT, padx=5)
- ttk.Button(action_frame, text="🔍 Проверить надежность",
- command=self.check_strength).pack(side=tk.LEFT, padx=5)
-
- # История паролей
- history_frame = ttk.LabelFrame(main_frame, text="История паролей", padding="15")
- history_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 15))
-
- # Панель инструментов истории
- history_toolbar = ttk.Frame(history_frame)
- history_toolbar.pack(fill=tk.X, pady=(0, 10))
-
- ttk.Button(history_toolbar, text="🔄 Обновить",
- command=self.load_history).pack(side=tk.LEFT, padx=2)
- ttk.Button(history_toolbar, text="🗑️ Очистить",
- command=self.clear_history_confirm).pack(side=tk.LEFT, padx=2)
- ttk.Button(history_toolbar, text="📤 Экспорт",
- command=self.export_history).pack(side=tk.LEFT, padx=2)
- ttk.Button(history_toolbar, text="📊 Статистика",
- command=self.show_statistics).pack(side=tk.LEFT, padx=2)
-
- # Таблица истории
- columns = ('id', 'password', 'strength', 'timestamp')
- self.history_tree = ttk.Treeview(history_frame, columns=columns, show='headings', height=8)
-
- self.history_tree.heading('id', text='ID')
- self.history_tree.heading('password', text='Пароль')
- self.history_tree.heading('strength', text='Надежность')
- self.history_tree.heading('timestamp', text='Время создания')
-
- self.history_tree.column('id', width=50, anchor='center')
- self.history_tree.column('password', width=200)
- self.history_tree.column('strength', width=100, anchor='center')
- self.history_tree.column('timestamp', width=150)
-
- scrollbar = ttk.Scrollbar(history_frame, orient=tk.VERTICAL, command=self.history_tree.yview)
- self.history_tree.configure(yscrollcommand=scrollbar.set)
-
- self.history_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
- scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
-
- # Привязка событий
- self.history_tree.bind('<Double-Button-1>', self.on_history_select)
-
- # Статус бар
- self.status_bar = ttk.Label(main_frame, text="Готов к работе", relief=tk.SUNKEN)
- self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
-
- # Меню
- self.create_menu()
-
- def create_menu(self):
- menubar = tk.Menu(self.root)
- self.root.config(menu=menubar)
-
- # Меню Файл
- file_menu = tk.Menu(menubar, tearoff=0)
- menubar.add_cascade(label="Файл", menu=file_menu)
- file_menu.add_command(label="Сохранить настройки", command=self.save_config)
- file_menu.add_command(label="Загрузить настройки", command=self.load_config)
- file_menu.add_separator()
- file_menu.add_command(label="Экспорт всех паролей", command=self.export_all_passwords)
- file_menu.add_separator()
- file_menu.add_command(label="Выход", command=self.root.quit)
-
- # Меню Настройки
- settings_menu = tk.Menu(menubar, tearoff=0)
- menubar.add_cascade(label="Настройки", menu=settings_menu)
- settings_menu.add_command(label="Ограничение истории",
- command=self.set_history_limit)
- settings_menu.add_command(label="Сбросить настройки",
- command=self.reset_settings)
-
- # Меню Справка
- help_menu = tk.Menu(menubar, tearoff=0)
- menubar.add_cascade(label="Справка", menu=help_menu)
- help_menu.add_command(label="О программе", command=self.show_about)
- help_menu.add_command(label="Рекомендации", command=self.show_tips)
-
- def init_database(self):
- try:
- conn = sqlite3.connect('passwords.db')
- cursor = conn.cursor()
-
- # Проверяем существование таблицы
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='passwords'")
- table_exists = cursor.fetchone()
-
- if table_exists:
- # Проверяем структуру существующей таблицы
- cursor.execute("PRAGMA table_info(passwords)")
- columns = cursor.fetchall()
- column_names = [col[1] for col in columns]
-
- # Если таблица создавалась по старому коду, пересоздаем её
- if 'generated_password' in column_names:
- # Сохраняем старые данные
- cursor.execute("SELECT generated_password, timestamp FROM passwords")
- old_data = cursor.fetchall()
-
- # Удаляем старую таблицу
- cursor.execute("DROP TABLE passwords")
-
- # Создаем новую таблицу
- cursor.execute('''
- CREATE TABLE passwords (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- password TEXT NOT NULL,
- strength TEXT,
- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
- )
- ''')
-
- # Восстанавливаем данные
- for data in old_data:
- password = data[0]
- timestamp = data[1]
- strength = self.calculate_strength(password)
- cursor.execute('''
- INSERT INTO passwords (password, strength, timestamp)
- VALUES (?, ?, ?)
- ''', (password, strength, timestamp))
- elif 'password' not in column_names:
- # Таблица существует, но нет колонки password - добавляем
- cursor.execute('''
- ALTER TABLE passwords ADD COLUMN password TEXT
- ''')
- else:
- # Создаем новую таблицу
- cursor.execute('''
- CREATE TABLE passwords (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- password TEXT NOT NULL,
- strength TEXT,
- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
- )
- ''')
-
- conn.commit()
- conn.close()
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Ошибка инициализации БД: {str(e)}")
-
- def generate_password(self):
- try:
- length = self.length_var.get()
- selected_chars = ''
-
- if self.letters_var.get():
- letters = string.ascii_letters
- if self.exclude_similar.get():
- letters = letters.replace('i', '').replace('l', '').replace('I', '').replace('L', '')
- letters = letters.replace('o', '').replace('O', '')
- selected_chars += letters
-
- if self.digits_var.get():
- digits = string.digits
- if self.exclude_similar.get():
- digits = digits.replace('0', '').replace('1', '')
- selected_chars += digits
-
- if self.punctuation_var.get():
- punctuation = string.punctuation
- if self.exclude_ambiguous.get():
- ambiguous = '{}[]()<>\\|`~'
- for char in ambiguous:
- punctuation = punctuation.replace(char, '')
- selected_chars += punctuation
-
- if not selected_chars:
- messagebox.showwarning("Предупреждение",
- "Выберите хотя бы один тип символов!")
- return
-
- # Гарантируем хотя бы по одному символу каждого выбранного типа
- password_chars = []
- if self.letters_var.get():
- letters = string.ascii_letters
- if self.exclude_similar.get():
- letters = letters.replace('i', '').replace('l', '').replace('I', '').replace('L', '')
- letters = letters.replace('o', '').replace('O', '')
- password_chars.append(random.choice(letters))
- length -= 1
-
- if self.digits_var.get():
- digits = string.digits
- if self.exclude_similar.get():
- digits = digits.replace('0', '').replace('1', '')
- password_chars.append(random.choice(digits))
- length -= 1
-
- if self.punctuation_var.get():
- punctuation = string.punctuation
- if self.exclude_ambiguous.get():
- ambiguous = '{}[]()<>\\|`~'
- for char in ambiguous:
- punctuation = punctuation.replace(char, '')
- password_chars.append(random.choice(punctuation))
- length -= 1
-
- # Добавляем остальные случайные символы
- for _ in range(max(0, length)):
- password_chars.append(random.choice(selected_chars))
-
- # Перемешиваем символы
- random.shuffle(password_chars)
- password = ''.join(password_chars)
-
- self.current_password = password
- self.password_var.set(password)
-
- # Определяем цвет в зависимости от надежности
- strength = self.calculate_strength(password)
- color = self.get_strength_color(strength)
- self.password_entry.config(foreground=color)
-
- self.status_bar.config(text=f"Пароль сгенерирован | Надежность: {strength}")
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Произошла ошибка: {str(e)}")
-
- def calculate_strength(self, password):
- score = 0
-
- # Длина
- if len(password) >= 20:
- score += 3
- elif len(password) >= 16:
- score += 2
- elif len(password) >= 12:
- score += 1
-
- # Разнообразие символов
- has_upper = any(c.isupper() for c in password)
- has_lower = any(c.islower() for c in password)
- has_digit = any(c.isdigit() for c in password)
- has_special = any(c in string.punctuation for c in password)
-
- types_count = sum([has_upper, has_lower, has_digit, has_special])
- score += types_count
-
- # Сложность
- if len(set(password)) / len(password) > 0.7:
- score += 1
-
- if score >= 6:
- return "Очень надежный"
- elif score >= 4:
- return "Надежный"
- elif score >= 2:
- return "Средний"
- else:
- return "Слабый"
-
- def get_strength_color(self, strength):
- colors = {
- "Очень надежный": "green",
- "Надежный": "blue",
- "Средний": "orange",
- "Слабый": "red"
- }
- return colors.get(strength, "black")
-
- def copy_to_clipboard(self):
- if self.current_password:
- self.root.clipboard_clear()
- self.root.clipboard_append(self.current_password)
- self.status_bar.config(text="Пароль скопирован в буфер обмена")
- messagebox.showinfo("Успех", "Пароль скопирован в буфер обмена!")
- else:
- messagebox.showwarning("Предупреждение", "Сначала сгенерируйте пароль!")
-
- def save_password(self):
- if not self.current_password:
- messagebox.showwarning("Предупреждение", "Сначала сгенерируйте пароль!")
- return
-
- try:
- conn = sqlite3.connect('passwords.db')
- cursor = conn.cursor()
-
- strength = self.calculate_strength(self.current_password)
-
- cursor.execute('''
- INSERT INTO passwords (password, strength, timestamp)
- VALUES (?, ?, ?)
- ''', (self.current_password, strength, datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
-
- conn.commit()
- conn.close()
-
- self.load_history()
- self.status_bar.config(text="Пароль сохранен в базу данных")
- messagebox.showinfo("Успех", "Пароль успешно сохранен!")
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Не удалось сохранить пароль: {str(e)}")
-
- def load_history(self):
- try:
- # Очищаем дерево
- for item in self.history_tree.get_children():
- self.history_tree.delete(item)
-
- conn = sqlite3.connect('passwords.db')
- cursor = conn.cursor()
-
- cursor.execute('''
- SELECT id, password, strength, timestamp
- FROM passwords
- ORDER BY id DESC
- LIMIT ?
- ''', (self.history_limit,))
-
- records = cursor.fetchall()
-
- for record in records:
- # Маскируем пароль для отображения
- masked_password = self.mask_password(record[1])
- self.history_tree.insert('', 'end', values=(
- record[0], masked_password, record[2], record[3]
- ))
-
- conn.close()
-
- self.status_bar.config(text=f"Загружено {len(records)} записей")
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Не удалось загрузить историю: {str(e)}")
-
- def mask_password(self, password):
- if not password:
- return "****"
- if len(password) <= 4:
- return "****"
- return password[:2] + "*" * (len(password) - 4) + password[-2:]
-
- def on_history_select(self, event):
- selection = self.history_tree.selection()
- if selection:
- item = self.history_tree.item(selection[0])
- item_id = item['values'][0]
-
- conn = sqlite3.connect('passwords.db')
- cursor = conn.cursor()
- cursor.execute('SELECT password FROM passwords WHERE id = ?', (item_id,))
- result = cursor.fetchone()
- conn.close()
-
- if result:
- password = result[0]
- self.current_password = password
- self.password_var.set(password)
- self.status_bar.config(text=f"Выбран пароль ID: {item_id}")
-
- def clear_history_confirm(self):
- if messagebox.askyesno("Подтверждение",
- "Вы уверены, что хотите очистить всю историю паролей?"):
- self.clear_history()
-
- def clear_history(self):
- try:
- conn = sqlite3.connect('passwords.db')
- cursor = conn.cursor()
- cursor.execute("DELETE FROM passwords")
- conn.commit()
- conn.close()
-
- self.load_history()
- messagebox.showinfo("Успех", "История паролей очищена!")
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Не удалось очистить историю: {str(e)}")
-
- def check_strength(self):
- if not self.current_password:
- messagebox.showwarning("Предупреждение", "Сначала сгенерируйте пароль!")
- return
-
- strength = self.calculate_strength(self.current_password)
- color = self.get_strength_color(strength)
-
- analysis = self.analyze_password(self.current_password)
-
- messagebox.showinfo("Анализ пароля",
- f"Надежность: {strength}\n\n"
- f"Длина: {len(self.current_password)} символов\n"
- f"Заглавные буквы: {'Есть' if any(c.isupper() for c in self.current_password) else 'Нет'}\n"
- f"Строчные буквы: {'Есть' if any(c.islower() for c in self.current_password) else 'Нет'}\n"
- f"Цифры: {'Есть' if any(c.isdigit() for c in self.current_password) else 'Нет'}\n"
- f"Спецсимволы: {'Есть' if any(c in string.punctuation for c in self.current_password) else 'Нет'}\n\n"
- f"{analysis}")
-
- def analyze_password(self, password):
- suggestions = []
-
- if len(password) < 12:
- suggestions.append("• Увеличьте длину пароля (рекомендуется 12+ символов)")
-
- if not any(c.isupper() for c in password):
- suggestions.append("• Добавьте заглавные буквы")
-
- if not any(c.islower() for c in password):
- suggestions.append("• Добавьте строчные буквы")
-
- if not any(c.isdigit() for c in password):
- suggestions.append("• Добавьте цифры")
-
- if not any(c in string.punctuation for c in password):
- suggestions.append("• Добавьте специальные символы")
-
- if len(set(password)) / len(password) < 0.6:
- suggestions.append("• Используйте больше уникальных символов")
-
- if suggestions:
- return "Рекомендации:\n" + "\n".join(suggestions)
- else:
- return "Пароль соответствует всем рекомендациям безопасности!"
-
- def export_history(self):
- try:
- conn = sqlite3.connect('passwords.db')
- cursor = conn.cursor()
- cursor.execute('SELECT * FROM passwords ORDER BY id DESC')
- records = cursor.fetchall()
- conn.close()
-
- if not records:
- messagebox.showwarning("Предупреждение", "Нет данных для экспорта!")
- return
-
- filename = f"passwords_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
-
- with open(filename, 'w', encoding='utf-8') as f:
- f.write("Экспорт паролей\n")
- f.write("=" * 50 + "\n\n")
-
- for record in records:
- f.write(f"ID: {record[0]}\n")
- f.write(f"Пароль: {record[1]}\n")
- f.write(f"Надежность: {record[2]}\n")
- f.write(f"Создан: {record[3]}\n")
- f.write("-" * 30 + "\n")
-
- self.status_bar.config(text=f"Данные экспортированы в файл: {filename}")
- messagebox.showinfo("Успех", f"Данные успешно экспортированы в файл:\n{filename}")
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Ошибка экспорта: {str(e)}")
-
- def export_all_passwords(self):
- self.export_history()
-
- def show_statistics(self):
- try:
- conn = sqlite3.connect('passwords.db')
- cursor = conn.cursor()
-
- cursor.execute("SELECT COUNT(*) FROM passwords")
- total = cursor.fetchone()[0]
-
- cursor.execute("SELECT COUNT(*) FROM passwords WHERE strength = 'Очень надежный'")
- very_strong = cursor.fetchone()[0]
-
- cursor.execute("SELECT COUNT(*) FROM passwords WHERE strength = 'Надежный'")
- strong = cursor.fetchone()[0]
-
- cursor.execute("SELECT COUNT(*) FROM passwords WHERE strength = 'Средний'")
- medium = cursor.fetchone()[0]
-
- cursor.execute("SELECT COUNT(*) FROM passwords WHERE strength = 'Слабый'")
- weak = cursor.fetchone()[0]
-
- cursor.execute("SELECT MIN(timestamp), MAX(timestamp) FROM passwords")
- dates = cursor.fetchone()
-
- conn.close()
-
- stats_text = f"""
- 📊 Статистика паролей
-
- Всего паролей: {total}
-
- По надежности:
- • Очень надежные: {very_strong}
- • Надежные: {strong}
- • Средние: {medium}
- • Слабые: {weak}
-
- Временной диапазон:
- • Первый пароль: {dates[0] if dates[0] else 'Нет данных'}
- • Последний пароль: {dates[1] if dates[1] else 'Нет данных'}
- """
-
- messagebox.showinfo("Статистика", stats_text)
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Не удалось получить статистику: {str(e)}")
-
- def set_history_limit(self):
- dialog = tk.Toplevel(self.root)
- dialog.title("Ограничение истории")
- dialog.geometry("300x150")
-
- tk.Label(dialog, text="Максимальное количество записей:").pack(pady=10)
-
- limit_var = tk.IntVar(value=self.history_limit)
- spinbox = tk.Spinbox(dialog, from_=5, to=100, textvariable=limit_var, width=10)
- spinbox.pack(pady=10)
-
- def apply_limit():
- self.history_limit = limit_var.get()
- self.load_history()
- dialog.destroy()
- messagebox.showinfo("Успех", f"Лимит истории установлен: {self.history_limit}")
-
- tk.Button(dialog, text="Применить", command=apply_limit).pack(pady=10)
-
- def save_config(self):
- config = {
- 'length': self.length_var.get(),
- 'letters': self.letters_var.get(),
- 'digits': self.digits_var.get(),
- 'punctuation': self.punctuation_var.get(),
- 'exclude_similar': self.exclude_similar.get(),
- 'exclude_ambiguous': self.exclude_ambiguous.get(),
- 'history_limit': self.history_limit
- }
-
- try:
- with open(self.config_file, 'w') as f:
- json.dump(config, f)
-
- self.status_bar.config(text="Настройки сохранены")
- messagebox.showinfo("Успех", "Настройки успешно сохранены!")
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Не удалось сохранить настройки: {str(e)}")
-
- def load_config(self):
- if not os.path.exists(self.config_file):
- return
-
- try:
- with open(self.config_file, 'r') as f:
- config = json.load(f)
-
- self.length_var.set(config.get('length', 16))
- self.letters_var.set(config.get('letters', True))
- self.digits_var.set(config.get('digits', True))
- self.punctuation_var.set(config.get('punctuation', True))
- self.exclude_similar.set(config.get('exclude_similar', True))
- self.exclude_ambiguous.set(config.get('exclude_ambiguous', False))
- self.history_limit = config.get('history_limit', 15)
-
- self.status_bar.config(text="Настройки загружены")
-
- except Exception as e:
- messagebox.showerror("Ошибка", f"Не удалось загрузить настройки: {str(e)}")
-
- def reset_settings(self):
- if messagebox.askyesno("Подтверждение",
- "Вы уверены, что хотите сбросить все настройки к значениям по умолчанию?"):
- self.length_var.set(16)
- self.letters_var.set(True)
- self.digits_var.set(True)
- self.punctuation_var.set(True)
- self.exclude_similar.set(True)
- self.exclude_ambiguous.set(False)
- self.history_limit = 15
-
- messagebox.showinfo("Успех", "Настройки сброшены к значениям по умолчанию!")
-
- def show_about(self):
- about_text = """
- 🔐 Генератор надежных паролей PRO
-
- Версия: 2.0
- Разработчик: Password Security Team
-
- Функции:
- • Генерация паролей с настройками
- • Проверка надежности паролей
- • Сохранение истории паролей
- • Экспорт данных
- • Статистика использования
-
- Используйте этот инструмент для создания
- безопасных паролей для всех ваших аккаунтов!
- """
- messagebox.showinfo("О программе", about_text)
-
- def show_tips(self):
- tips = """
- 💡 Советы по созданию надежных паролей:
-
- 1. Используйте длину не менее 12 символов
- 2. Сочетайте разные типы символов
- 3. Избегайте личной информации
- 4. Не используйте один пароль на всех сайтах
- 5. Регулярно меняйте важные пароли
- 6. Используйте менеджер паролей
- 7. Включайте двухфакторную аутентификацию
-
- Помните: Лучший пароль - тот, который вы не можете запомнить,
- но ваш менеджер паролей может!
- """
- messagebox.showinfo("Рекомендации по безопасности", tips)
-
- def run(self):
- self.load_history()
- self.root.mainloop()
- if __name__ == "__main__":
- app = PasswordGenerator()
- app.run()
|