Table of Contents
هدف پروژه: تولید خودکار رمزهای عبور امن
در این پروژه یک برنامهٔ پایتون مینویسید که برای شما رمزهای عبور تصادفی، قوی و قابل تنظیم بسازد. ایدهٔ اصلی این است که بهجای انتخاب رمزهای ساده مثل 123456 یا password، هر بار با اجرای برنامه یک رمز جدید بسازید.
در این پروژه تمرین میکنید:
- کار با رشتهها و لیستها
- استفاده از حلقهها
- استفاده از کتابخانههای استاندارد مثل
randomو (در نسخهٔ امنتر)secrets - گرفتن ورودی از کاربر و ساختن یک برنامهٔ تعاملی کوچک
طراحی سادهٔ تولیدکنندهٔ رمز عبور
اول یک نسخهٔ ساده میسازیم:
- طول رمز را از کاربر میپرسیم
- از حروف کوچک و بزرگ، اعداد و چند نشانه استفاده میکنیم
- یک رشتهٔ تصادفی با آن طول میسازیم
مثلاً:
- حروف کوچک:
abcdefghijklmnopqrstuvwxyz - حروف بزرگ:
ABCDEFGHIJKLMNOPQRSTUVWXYZ - اعداد:
0123456789 - نشانهها:
!@#$%^&*()_+
قدم ۱: ساختن نسخهٔ پایه
import random
# کاراکترهای قابل استفاده
lowercase = "abcdefghijklmnopqrstuvwxyz"
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
digits = "0123456789"
symbols = "!@#$%^&*()_+"
all_chars = lowercase + uppercase + digits + symbols
length = int(input("طول رمز عبور را وارد کنید: "))
password = ""
for i in range(length):
password += random.choice(all_chars)
print("رمز عبور شما:")
print(password)نکتهها:
- از
+برای چسباندن رشتهها استفاده کردیم تا مجموعهای از کاراکترهای مجاز بسازیم. - در هر دور حلقه، یک کاراکتر تصادفی انتخاب و به آخر رشتهٔ
passwordاضافه میکنیم.
تنظیم گزینهها توسط کاربر
نسخهٔ بهتر این است که کاربر بتواند مشخص کند چه نوع کاراکتری در رمز استفاده شود:
- آیا حروف کوچک باشد؟
- حروف بزرگ چطور؟
- عدد داشته باشد؟
- نشانهٔ خاص داشته باشد؟
پرسیدن گزینهها
میتوانیم از کاربر سؤالهای بله/خیر بپرسیم و براساس آنها مجموعهٔ کاراکترها را بسازیم:
import random
lowercase = "abcdefghijklmnopqrstuvwxyz"
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
digits = "0123456789"
symbols = "!@#$%^&*()_+"
length = int(input("طول رمز عبور را وارد کنید: "))
use_lower = input("حروف کوچک استفاده شود؟ (y/n): ")
use_upper = input("حروف بزرگ استفاده شود؟ (y/n): ")
use_digits = input("اعداد استفاده شود؟ (y/n): ")
use_symbols = input("نشانهها استفاده شود؟ (y/n): ")
allowed = ""
if use_lower == "y":
allowed += lowercase
if use_upper == "y":
allowed += uppercase
if use_digits == "y":
allowed += digits
if use_symbols == "y":
allowed += symbols
if allowed == "":
print("هیچ نوع کاراکتری انتخاب نشده است! برنامه متوقف میشود.")
else:
password = ""
for i in range(length):
password += random.choice(allowed)
print("رمز عبور شما:")
print(password)نکتهٔ مهم: اگر کاربر هیچ گزینهای را انتخاب نکند، باید یک پیام خطا بدهیم و رمز نسازیم.
اطمینان از حضور همهٔ انواع انتخابشده
در نسخهٔ قبلی ممکن است کاربر بگوید «اعداد و حروف بزرگ را استفاده کن»، اما شانسی طوری شود که در رمز تولیدشده عددی وجود نداشته باشد. برای رمز قویتر بهتر است:
- اگر کاربر یک نوع کاراکتر را انتخاب کرده، حداقل یک کاراکتر از آن نوع در رمز قرار بگیرد.
ایدهٔ حل
۱. برای هر نوع انتخابشده، یک کاراکتر تصادفی از همان گروه را اجباری به رمز اضافه میکنیم.
۲. بقیهٔ طول رمز را با کاراکترهای تصادفی از کل allowed پر میکنیم.
۳. در پایان، ترتیب کاراکترها را بهصورت تصادفی بههم میزنیم (shuffle).
پیادهسازی این ایده
import random
lowercase = "abcdefghijklmnopqrstuvwxyz"
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
digits = "0123456789"
symbols = "!@#$%^&*()_+"
length = int(input("طول رمز عبور را وارد کنید: "))
use_lower = input("حروف کوچک استفاده شود؟ (y/n): ")
use_upper = input("حروف بزرگ استفاده شود؟ (y/n): ")
use_digits = input("اعداد استفاده شود؟ (y/n): ")
use_symbols = input("نشانهها استفاده شود؟ (y/n): ")
allowed = ""
password_chars = [] # اینجا کاراکترها را موقت نگه میداریم
if use_lower == "y":
allowed += lowercase
password_chars.append(random.choice(lowercase))
if use_upper == "y":
allowed += uppercase
password_chars.append(random.choice(uppercase))
if use_digits == "y":
allowed += digits
password_chars.append(random.choice(digits))
if use_symbols == "y":
allowed += symbols
password_chars.append(random.choice(symbols))
if allowed == "":
print("هیچ نوع کاراکتری انتخاب نشده است! برنامه متوقف میشود.")
else:
# حالا بقیهٔ کاراکترها را پر میکنیم
while len(password_chars) < length:
password_chars.append(random.choice(allowed))
# بههم زدن ترتیب کاراکترها
random.shuffle(password_chars)
# تبدیل لیست به رشته
password = "".join(password_chars)
print("رمز عبور شما:")
print(password)اینجا از:
listبرای نگهداشتن کاراکترها استفاده کردیم- متد
random.shuffleبرای بههمزدن ترتیب - متد
"".join(...)برای تبدیل لیست کاراکترها به یک رشته
نسخهٔ امنتر با کتابخانهٔ secrets
کتابخانهٔ random برای شبیهسازی و کارهای معمولی مناسب است، اما برای امنیت و رمزنگاری، پایتون کتابخانهٔ امنتری بهنام secrets دارد که برای تولید رمز عبور پیشنهاد میشود.
نسخهٔ ساده با secrets:
import secrets
import string # کتابخانهٔ استاندارد برای گروههای کاراکترها
# استفاده از مجموعه کاراکترهای آماده
lowercase = string.ascii_lowercase
uppercase = string.ascii_uppercase
digits = string.digits
symbols = "!@#$%^&*()_+"
all_chars = lowercase + uppercase + digits + symbols
length = int(input("طول رمز عبور را وارد کنید: "))
password = "".join(secrets.choice(all_chars) for _ in range(length))
print("رمز عبور (امنتر) شما:")
print(password)تفاوت مهم:
secrets.choiceبرای انتخاب تصادفی امنتر استفاده میشود.
(توضیح کامل امنیت و رمزنگاری در این فصل نمیآید؛ فقط ایدهٔ «امنتر بودن» معرفی میشود.)
قرار دادن کد در تابع
برای مرتبتر شدن و استفادهٔ مجدد، میتوانیم منطق تولید رمز را در یک تابع قرار دهیم. در اینجا یک نسخهٔ نسبتاً کامل و قابلاستفاده را میبینید.
import secrets
import string
def generate_password(length=12, use_lower=True, use_upper=True,
use_digits=True, use_symbols=True):
lowercase = string.ascii_lowercase
uppercase = string.ascii_uppercase
digits = string.digits
symbols = "!@#$%^&*()_+"
allowed = ""
password_chars = []
if use_lower:
allowed += lowercase
password_chars.append(secrets.choice(lowercase))
if use_upper:
allowed += uppercase
password_chars.append(secrets.choice(uppercase))
if use_digits:
allowed += digits
password_chars.append(secrets.choice(digits))
if use_symbols:
allowed += symbols
password_chars.append(secrets.choice(symbols))
if allowed == "":
raise ValueError("هیچ نوع کاراکتری انتخاب نشده است.")
# اگر طول کمتر از تعداد گروههای انتخابشده باشد
if length < len(password_chars):
raise ValueError("طول رمز از تعداد گروههای انتخابشده کمتر است.")
# بقیهٔ کاراکترها
while len(password_chars) < length:
password_chars.append(secrets.choice(allowed))
# بههمزدن
secrets.SystemRandom().shuffle(password_chars)
return "".join(password_chars)
# استفادهٔ تعاملی
length = int(input("طول رمز عبور را وارد کنید (مثلاً ۱۲): "))
use_lower = input("حروف کوچک استفاده شود؟ (y/n): ") == "y"
use_upper = input("حروف بزرگ استفاده شود؟ (y/n): ") == "y"
use_digits = input("اعداد استفاده شود؟ (y/n): ") == "y"
use_symbols = input("نشانهها استفاده شود؟ (y/n): ") == "y"
try:
pwd = generate_password(length, use_lower, use_upper, use_digits, use_symbols)
print("رمز عبور شما:")
print(pwd)
except ValueError as e:
print("خطا:", e)این نسخه:
- با تابع
generate_passwordقابل استفاده در جاهای دیگر برنامه هم هست - در صورت تنظیمات نامعتبر، خطا تولید میکند (که در
try/exceptگرفته شده است)
ایدههایی برای گسترش پروژه
اگر میخواهید پروژه را کمی پیشرفتهتر کنید، میتوانید:
- گزینهای اضافه کنید که چندین رمز بهصورت همزمان بسازد (مثلاً ۵ رمز پشت سر هم).
- گزینهای برای ذخیرهٔ رمزها در یک فایل متنی (با هشدار: استفادهٔ واقعی از این روش ناامن است).
- نمایش «قدرت تقریبی» رمز براساس طول و نوع کاراکترها (کنار هر رمز، عبارتی مانند «ضعیف / متوسط / قوی»).
- استفاده از یک منوی ساده (مثلاً با
while True) تا کاربر بتواند چند بار پشت سر هم رمز تولید کند و در انتها گزینهٔ خروج را انتخاب کند.
این پروژه یک نمونهٔ خوب از ترکیب چند مفهوم است: ورودی/خروجی، حلقهها، رشتهها، توابع و کتابخانههای استاندارد؛ و نتیجهٔ آن هم ابزاری است که واقعاً میتوانید از آن استفاده کنید.