ساخت برنامه‌ی بررسی قدرت رمز عبور با Python و CustomTkinter

پروژه ۶ دقیقه مطالعه
فهرست مطالب
این مطلب از سایت tool.hamidvalad.ir گرفته شده است

معرفی

در دنیای دیجیتال امروز، امنیت رمز عبور یکی از مهم‌ترین اصول برای محافظت از اطلاعات شخصی و حساب‌های آنلاین است. بسیاری از کاربران هنگام انتخاب رمز، نکات امنیتی را رعایت نمی‌کنند و از رمزهای ساده و قابل حدس استفاده می‌کنند که خطر نفوذ را افزایش می‌دهد.

در این مقاله، به بررسی یک پروژه عملی پایتون می‌پردازیم که با استفاده از CustomTkinter یک رابط گرافیکی ایجاد می‌کند تا قدرت و امنیت رمز عبور کاربران را به صورت لحظه‌ای بررسی کند. این برنامه ویژگی‌های مختلف رمز شامل طول، وجود حروف بزرگ و کوچک، اعداد و کاراکترهای ویژه را ارزیابی کرده و بر اساس آن نمره‌ای به رمز اختصاص می‌دهد. همچنین یک نوار پیشرفت رنگی نمایش داده می‌شود تا کاربر به سرعت متوجه شود که رمزش ضعیف، متوسط یا قوی است.

این پروژه نه تنها به عنوان یک ابزار آموزشی برای یادگیری رابط گرافیکی پایتون و مدیریت متغیرها و رویدادها کاربرد دارد، بلکه می‌تواند به کاربران کمک کند تا رمزهای امن‌تر و مقاوم‌تری بسازند و عادت‌های امنیتی بهتری پیدا کنند.

پیش‌نیازها

برای اجرای برنامه‌ی بررسی قدرت رمز عبور با CustomTkinter، باید مطمئن شوید که کتابخانه‌های زیر روی سیستم شما نصب هستند:

  1. Python 3
    برنامه با نسخه‌های پایتون ۳ اجرا می‌شود. پیشنهاد می‌کنیم آخرین نسخه پایدار پایتون ۳ را نصب کنید.
  2. customtkinter
    این کتابخانه برای ایجاد رابط گرافیکی مدرن و زیبا استفاده می‌شود.
    نصب با pip:
    pip install customtkinter
  3. re
    این کتابخانه استاندارد پایتون برای بررسی الگوهای متنی (Regex) استفاده می‌شود. نیازی به نصب ندارد.
  4. string
    برای کار با مجموعه‌های حروف، اعداد و کاراکترها استفاده می‌شود. نیازی به نصب ندارد.
  5. random
    برای تولید رمز عبور تصادفی استفاده می‌شود. نیازی به نصب ندارد.

راهنمای راه‌اندازی برنامه

برای اجرای برنامه‌ی بررسی قدرت رمز عبور با CustomTkinter مراحل زیر را دنبال کنید:

  1. دانلود یا ایجاد فایل برنامه
    ابتدا کد برنامه را در یک فایل با پسوند .py ذخیره کنید، مثلاً:
    password_checker.py
  2. اطمینان از نصب پیش‌نیازها
    مطمئن شوید پایتون ۳ روی سیستم شما نصب است و کتابخانه customtkinter را نصب کنید:
    pip install customtkinter
  3. اجرای برنامه
    در ترمینال یا CMD به مسیر فایل برنامه بروید:
    cd مسیر/فایل/برنامه
    سپس برنامه را اجرا کنید:
    python password_checker.py
  4. استفاده از برنامه
    • پس از اجرای برنامه، پنجره گرافیکی ظاهر می‌شود.
    • رمز عبور خود را در قسمت ورودی وارد کنید.
    • نوار پیشرفت رنگی وضعیت رمز را نشان می‌دهد:
      • قرمز : ضعیف
      • نارنجی : متوسط
      • سبز : قوی
    • می‌توانید با دکمه «تولید رمز تصادفی» یک رمز امن بسازید یا با دکمه «کپی رمز» رمز وارد شده را کپی کنید.
    • گزینه «نمایش رمز» برای دیدن متن رمز فعال است.

کد برنامه

در ادامه کد کامل برنامه قرار دارد. این کد منطق بررسی رمز، رابط گرافیکی و عملکردهای کمکی را پیاده‌سازی می‌کند:

import customtkinter as ctk
import re
import string
import random

ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")

MIN_LENGTH = 8

def has_lower(s):
    return bool(re.search(r"[a-z]", s))

def has_upper(s):
    return bool(re.search(r"[A-Z]", s))

def has_digit(s):
    return bool(re.search(r"\d", s))

def has_special(s):
    return bool(re.search(r"[^A-Za-z0-9]", s))

def length_ok(s):
    return len(s) >= MIN_LENGTH

def evaluate_password(pw):
    checks = {
        "length": length_ok(pw),
        "lower": has_lower(pw),
        "upper": has_upper(pw),
        "digit": has_digit(pw),
        "special": has_special(pw),
    }
    weight = {"length":0.35, "lower":0.15, "upper":0.15, "digit":0.15, "special":0.2}
    score = sum(weight[k] for k,v in checks.items() if v)
    return checks, min(1.0, score)

def strength_text_and_color(score):
    if score < 0.33: return "ضعیف", "#e74c3c"
    elif score < 0.66: return "متوسط", "#e67e22"
    else: return "قوی", "#2ecc71"

class PasswordCheckerApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("Password Strength Checker")
        self.geometry("560x420")
        self.resizable(False, False)

        header = ctk.CTkLabel(self, text="بررسی قوی / ضعیف بودن رمز عبور", font=(None, 20))
        header.pack(pady=(16,8))
        sub = ctk.CTkLabel(self, text=f"حداقل طول: {MIN_LENGTH} کاراکتر. ترکیبی از حروف بزرگ/کوچک، عدد و کاراکتر ویژه.", font=(None,12))
        sub.pack(pady=(0,12))

        frm = ctk.CTkFrame(self, corner_radius=10)
        frm.pack(padx=16, pady=(0,12), fill="x")

        self.pw_var = ctk.StringVar()
        self.entry = ctk.CTkEntry(frm, placeholder_text="رمز عبور را وارد کنید...", textvariable=self.pw_var, width=380)
        self.entry.grid(row=0, column=0, padx=(12,8), pady=12, sticky="w")
        self.entry.bind("<KeyRelease>", self.on_type)

        self.show_var = ctk.BooleanVar(value=False)
        self.show_chk = ctk.CTkCheckBox(frm, text="نمایش رمز", variable=self.show_var, command=self.toggle_show)
        self.show_chk.grid(row=0, column=1, padx=8, pady=12, sticky="e")

        btn_frame = ctk.CTkFrame(self, fg_color="transparent")
        btn_frame.pack(fill="x", padx=16)

        self.copy_btn = ctk.CTkButton(btn_frame, text="کپی رمز", width=120, command=self.copy_password)
        self.copy_btn.pack(side="left", padx=(0,8))
        self.generate_btn = ctk.CTkButton(btn_frame, text="تولید رمز تصادفی", width=160, command=self.generate_password)
        self.generate_btn.pack(side="left")

        progress_frame = ctk.CTkFrame(self, corner_radius=8)
        progress_frame.pack(padx=16, pady=12, fill="x")
        self.progress = ctk.CTkProgressBar(progress_frame)
        self.progress.set(0.0)
        self.progress.pack(fill="x", padx=12, pady=(12,6))
        self.strength_label = ctk.CTkLabel(progress_frame, text="نمره: —", font=(None,13,"bold"))
        self.strength_label.pack(anchor="e", padx=12, pady=(0,12))

        rules_frame = ctk.CTkFrame(self, corner_radius=8)
        rules_frame.pack(padx=16, pady=(0,12), fill="both", expand=True)
        rules_title = ctk.CTkLabel(rules_frame, text="قوانین بررسی رمز:", font=(None,14,"bold"))
        rules_title.pack(anchor="w", padx=12, pady=(12,6))

        self.rule_labels = {}
        self.rules = [("length", f"حداقل {MIN_LENGTH} کاراکتر"),
                      ("lower", "وجود حرف کوچک (a-z)"),
                      ("upper", "وجود حرف بزرگ (A-Z)"),
                      ("digit", "وجود عدد (0-9)"),
                      ("special", "وجود کاراکتر ویژه (مثل !@#)")]
        for key,text in self.rules:
            lbl = ctk.CTkLabel(rules_frame, text=f"✖ {text}", anchor="w", font=(None,12))
            lbl.pack(fill="x", padx=16, pady=6)
            self.rule_labels[key] = lbl

        self.advice = ctk.CTkLabel(self, text="", font=(None,12), wraplength=520, justify="left")
        self.advice.pack(padx=16, pady=(6,16))
        self.update_ui("")

    def on_type(self, event=None):
        self.update_ui(self.pw_var.get())

    def toggle_show(self):
        self.entry.configure(show="" if self.show_var.get() else "*")

    def copy_password(self):
        pw = self.pw_var.get()
        if pw:
            self.clipboard_clear()
            self.clipboard_append(pw)
            self.copy_btn.configure(text="کپی شد ✅")
            self.after(1400, lambda: self.copy_btn.configure(text="کپی رمز"))
        else:
            self.copy_btn.configure(text="خالی است")
            self.after(1200, lambda: self.copy_btn.configure(text="کپی رمز"))

    def generate_password(self, length=12):
        chars = string.ascii_letters + string.digits + string.punctuation
        pw = ''.join(random.choice(chars) for _ in range(length))
        self.pw_var.set(pw)
        self.update_ui(pw)

    def update_ui(self, pw):
        checks, score = evaluate_password(pw)
        self.progress.set(score)
        text,color = strength_text_and_color(score)
        pct = int(score*100)
        self.strength_label.configure(text=f"نمره: {pct}% — {text}")
        for key,desc in self.rules:
            ok = checks[key]
            mark = "✔" if ok else "✖"
            lbl = self.rule_labels[key]
            lbl.configure(text=f"{mark} {desc}", text_color="#2ecc71" if ok else "#e74c3c")
        advice_lines = []
        if not checks["length"]: advice_lines.append(f"- رمز حداقل {MIN_LENGTH} کاراکتر باشد.")
        if not checks["lower"]: advice_lines.append("- از حروف کوچک مثل a,b استفاده کن.")
        if not checks["upper"]: advice_lines.append("- از حداقل یک حرف بزرگ مثل A,B استفاده کن.")
        if not checks["digit"]: advice_lines.append("- حداقل یک عدد وارد کن (مثلاً 3).")
        if not checks["special"]: advice_lines.append("- از کاراکترهای ویژه مثل !@#% استفاده کن.")
        self.advice.configure(text="نکات برای قوی‌تر کردن رمز:\n"+"\n".join(advice_lines) if advice_lines else "خوبه! رمز قوی‌ هست. ✅")

if __name__ == "__main__":
    app = PasswordCheckerApp()
    app.mainloop()

آیا بدون Tkinter و CustomTkinter هم می‌شود این برنامه را نوشت؟

بله، کاملاً می‌شود. منطق اصلی برنامه‌ی بررسی رمز عبور وابسته به رابط گرافیکی نیست، بلکه به تحلیل محتوای رشته‌ی رمز برمی‌گردد. بررسی تعداد کاراکترها، وجود عدد، حروف بزرگ، حروف کوچک و نشانه‌ها کاملاً با کدهای متنی و خط فرمان (CLI) هم قابل انجام است.

در نسخه‌ی ساده‌تر بدون رابط گرافیکی، می‌توان با input() از کاربر رمز گرفت و سپس با استفاده از کتابخانه‌های re و string قدرت رمز را بررسی و نتیجه را در ترمینال چاپ کرد (مثلاً: "رمز شما قوی است ✅" یا "رمز شما ضعیف است ⚠️").

تفاوت اصلی نحوه‌ی نمایش است: در نسخه‌ی بدون Tkinter همه چیز متنی و خطی است؛ در نسخه‌ی گرافیکی اطلاعات به‌صورت زنده، رنگی و با نوار قدرت نمایش داده می‌شود.

نکات مهم در کد

  1. ساخت رابط گرافیکی با CustomTkinter: ایجاد پنجره اصلی و سازماندهی ویجت‌ها (ورودی، دکمه‌ها، نوار پیشرفت).
  2. ورودی رمز عبور (Entry): با هر بار تایپ مقدار ورودی بررسی و آپدیت می‌شود.
  3. بررسی رمز با Regex: الگوهای منظم برای تشخیص حروف کوچک/بزرگ، عدد و کاراکتر ویژه استفاده شده‌اند.
  4. نوار قدرت (Progress Bar): مقدار و رنگ نوار بر اساس امتیاز رمز تغییر می‌کند (قرمز/نارنجی/سبز).
  5. دکمه تولید رمز تصادفی: تولید رمز امن با ترکیب حروف، اعداد و نمادها.
  6. تابع آپدیت لحظه‌ای: بررسی زنده هنگام تایپ برای بازخورد فوری به کاربر.
  7. دکمه نمایش/پنهان کردن رمز: قابلیت جابجایی بین حالت مخفی و نمایان رمز.
  8. طراحی تم و رنگ‌بندی: پشتیبانی از حالت‌های روشن/تاریک برای تجربه کاربری بهتر.

نتیجه‌گیری

در این پروژه یاد گرفتیم چطور با استفاده از پایتون و کتابخانه‌ی CustomTkinter یک برنامه‌ی گرافیکی بسازیم که قدرت رمز عبور کاربران را به‌صورت زنده ارزیابی کند. این پروژه ترکیبی از مفاهیم امنیت اطلاعات، رابط کاربری (GUI) و بررسی الگوهای متنی (Regex) است و می‌تواند هم برای یادگیری و هم برای استفاده در پروژه‌های واقعی مفید باشد.

نتیجه‌ی اصلی این مقاله این است که امنیت رمز عبور تنها با طول زیاد تأمین نمی‌شود؛ ترکیب حروف بزرگ و کوچک، عدد و نشانه‌ها نیز ضروری است. همچنین استفاده از رابط گرافیکی تجربه کاربری را بهبود می‌بخشد و یادگیری را جذاب‌تر می‌کند.

منابع

  1. Python Official Documentation – re (Regular Expressions)
  2. CustomTkinter Documentation
  3. Python string Module Documentation
  4. OWASP Foundation – Password Policy Recommendations