اعتبارسنجی را از هدف جدا نکنید

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

هر قاعده باید تعریف آزمون‌پذیر داشته باشد

عبارت «حرف و عدد داشته باشد» مبهم است. آیا حرف فارسی پذیرفته است؟ آیا رقم فارسی هم عدد محسوب می‌شود؟ در پروژهٔ مرتبط، گروه حرف و رقم به ASCII محدود شده و مجموعهٔ نمادها نیز صریح است. فاصله نماد قابل‌قبول نیست. این محدودیت برای آموزش قرارداد است، نه توصیهٔ عمومی محصول؛ در یک سامانهٔ واقعی سیاست انتخابی باید مستند و قابل‌توضیح باشد.

کاربرد any در بررسی رشته

تابع any زمانی درست می‌شود که دست‌کم یکی از شرط‌های تولیدشده درست باشد. می‌توان سه بررسی مستقل برای حرف، رقم و نماد نوشت و نتیجهٔ هرکدام را نگه داشت. این شکل از یک عبارت بسیار طولانی خواناتر است، چون هنگام شکست آزمون می‌فهمید کدام بخش متفاوت بوده است. اگر رشته خالی باشد، any روی آن نادرست است؛ لازم نیست برای هر گروه حلقهٔ جدا با متغیر کمکی بسازید.

تفاوت isdigit با محدودهٔ صریح

متد isdigit فقط رقم‌های انگلیسی را تشخیص نمی‌دهد و برای برخی نویسه‌های Unicode نیز درست برمی‌گرداند. اگر قرارداد شما فقط صفر تا نهٔ انگلیسی است، مقایسهٔ صریح نویسه با این محدوده مناسب‌تر است. همین نکته دربارهٔ isalpha وجود دارد. انتخاب این دو روش باید از سیاست داده بیاید؛ جایگزین‌کردن کورکورانهٔ آن‌ها ممکن است نتیجهٔ ورودی فارسی را بدون اطلاع کاربر تغییر دهد.

طول متن و نتیجهٔ نهایی

طول رشته در Python تعداد عناصر رشته است، نه تعداد بایت UTF-8 و نه لزوماً تعداد نمادهای بصری. برای دادهٔ ASCII این تمایز ساده‌تر است، اما ترکیب حرف و علامت اعراب می‌تواند ظاهر یک نویسه و طول چندتایی داشته باشد. نتیجهٔ نهایی را از شرط طول و سه بررسی مستقل بسازید. خروجی باید بولی واقعی باشد، نه رشتهٔ true یا false، تا مصرف‌کنندهٔ JSON تفسیر دیگری نداشته باشد.

چه چیزهایی نباید گزارش شوند؟

گزارش تمرین فقط طول و وضعیت عبور از قواعد را لازم دارد؛ خود رشته نباید دوباره در خروجی تکرار شود. در محصول واقعی، ورودی حساس نباید وارد log، ابزار تحلیل یا پیام خطای عمومی شود. این مثال صرفاً روی دادهٔ خیالی کار می‌کند. همچنین نام متغیر strong یک برچسب قراردادی در تمرین است و نباید در رابط محصول به‌عنوان تضمین مقاومت در برابر حدس یا افشا نمایش داده شود.

آزمون مرزها پیش از استفاده

رشتهٔ خالی، طول دقیقاً هشت، رشتهٔ فقط رقم، رشتهٔ دارای فاصله و رشتهٔ دارای رقم فارسی را جدا تست کنید. نمونه‌ای بسازید که سه گروه را دارد اما کوتاه است و نمونه‌ای دیگر که بلند است ولی یکی از گروه‌ها را ندارد. این دو تست نشان می‌دهند چرا باید همهٔ شرط‌ها با and ترکیب شوند. برای اعتبارسنجی، پوشش مرزها معمولاً از افزودن چند مثال تصادفی ارزشمندتر است.

نمونه‌کد و قرارداد پروژه

passwords: فهرست رشته‌های کاملاً ساختگی برای تمرین؛ هرگز گذرواژهٔ واقعی وارد نکنید. حروف و رقم‌ها فقط ASCII و نماد فقط مجموعهٔ !@#$%^&* هستند.

results: یک رکورد برای هر رشته به همان ترتیب؛ length طول رشته؛ has_letter و has_digit و has_symbol وجود گروه مربوطه؛ strong یعنی طول حداقل ۸ و وجود هر سه گروه. این قواعد تضمین امنیت نیستند.

def solve(data):
    results = []
    for value in data['passwords']:
        letter = any('a' <= c.lower() <= 'z' for c in value)
        digit = any('0' <= c <= '9' for c in value)
        symbol = any(c in '!@#$%^&*' for c in value)
        results.append({'length': len(value), 'has_letter': letter,
                        'has_digit': digit, 'has_symbol': symbol,
                        'strong': len(value) >= 8 and letter and digit and symbol})
    return {'results': results}

print(solve({'passwords': ['Python123!', 'short', 'abcdefghijk']}))

خروجی مورد انتظار

{
  "results": [
    {
      "length": 10,
      "has_letter": true,
      "has_digit": true,
      "has_symbol": true,
      "strong": true
    },
    {
      "length": 5,
      "has_letter": true,
      "has_digit": false,
      "has_symbol": false,
      "strong": false
    },
    {
      "length": 11,
      "has_letter": true,
      "has_digit": false,
      "has_symbol": false,
      "strong": false
    }
  ]
}

پرسش‌های متداول

آیا این روش برای سامانهٔ ورود کافی است؟

خیر. احراز هویت، نگه‌داری امن، محدودیت تلاش و سیاست‌های امنیتی حوزه‌های جدا هستند؛ این متن فقط منطق شرط‌های رشته را آموزش می‌دهد.

چرا رشتهٔ خالی نتیجهٔ نادرست دارد؟

چون نه طول لازم و نه هیچ‌یک از گروه‌های نویسه در آن وجود دارد؛ قرارداد باید این رفتار را از ابتدا مشخص کند.

تمرین عملی و قدم بعدی

پروژهٔ «ارزیابی سادهٔ گذرواژه» همین قرارداد را در میزکار ارزیابی می‌کند. ابتدا خروجی نمونه را دستی محاسبه کنید، سپس تابع را اجرا کنید و یک ورودی مرزی متفاوت بسازید. نمونه‌کد راهی برای توضیح منطق است؛ برای یادگیری، علت هر شرط و انتخاب ساختار داده را بدون نگاه‌کردن به کد توضیح دهید. اجرای موفق با قبولی ارزیابی متفاوت است؛ نتیجه باید برای تمام حالت‌های تعریف‌شده درست بماند.

منابع و مطالعهٔ بیشتر

برای بررسی جزئیات و ادامهٔ مطالعه؛ متن این راهنما مستقلاً برای نوونتیکس نوشته شده است.