ตัวสร้างรหัสผ่าน“ Crapcode”

Sep 27 2020

ฉันสร้างPassword Generatorบน C #

มันแจ้งให้ผู้ใช้สำหรับความยาวของรหัสผ่านไม่ว่าจะมีตัวเลข , ตัวพิมพ์เล็ก , ตัวพิมพ์ใหญ่หรือสัญลักษณ์และสร้างรหัสผ่านที่แข็งแกร่งจากการเพิ่มการสุ่มตัวเลขตัวอักษรหรือสัญลักษณ์

มีรหัส:

using System;

namespace Password_Generator
{
    class Program
    {
        static string Randomize(string Str)
        {
            Random Rand = new Random();

            string Randomized = "";

            while (Randomized.Length < Str.Length)
            {
                Randomized += Str[Rand.Next(0, Str.Length)];
            }

            return Randomized;
        }

        static void Main(string[] args)
        {
            while (true)
            {
                Console.ForegroundColor = ConsoleColor.White;

                Console.Write("\nDo Yout Want a New Password [True], [False]? ");
                Console.ForegroundColor = ConsoleColor.Yellow;
                string NewPasswordStr = Console.ReadLine();
                bool NewPassword;

                while (bool.TryParse(NewPasswordStr, out NewPassword) == false)
                {
                    Console.Clear();

                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("The Given Output is Unconvertable Or it's Value is Unacceptable. Try Again!");

                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write("\nDo Yout Want a New Password [True], [False]? ");

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    NewPasswordStr = Console.ReadLine();
                    Console.ForegroundColor = ConsoleColor.White;
                }

                Console.ForegroundColor = ConsoleColor.White;

                if (NewPassword == true)
                {
                    Console.Clear();

                    Console.Write("Password Length: ");

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    string LenghtStr = Console.ReadLine();
                    int Lenght;

                    while (int.TryParse(LenghtStr, out Lenght) == false || int.Parse(LenghtStr) <= 0)
                    {
                        Console.Clear();

                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("The Given Output is Unconvertable Or it's Value is Unacceptable. Try Again!");

                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write("\nPassword Length: ");

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        LenghtStr = Console.ReadLine();
                        Console.ForegroundColor = ConsoleColor.White;
                    }

                    Console.ForegroundColor = ConsoleColor.White;

                    Console.Write("\n\nInclude Numbers (0 - 9) [True], [False]: ");

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    string IncludeNumbersStr = Console.ReadLine();
                    bool IncludeNumbers;

                    while (bool.TryParse(IncludeNumbersStr, out IncludeNumbers) == false)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");

                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write("\nInclude Numbers (0 - 9) [True], [False]: ");

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        IncludeNumbersStr = Console.ReadLine();
                        Console.ForegroundColor = ConsoleColor.White;
                    }

                    Console.Write("\n\nInclude Lowercase Letters (a - z) [True], [False]: ");

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    string IncludeLowercaseStr = Console.ReadLine();
                    bool IncludeLowercase;

                    while (bool.TryParse(IncludeLowercaseStr, out IncludeLowercase) == false)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");

                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write("\nInclude Lowercase Letters (a - z) [True], [False]: ");

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        IncludeLowercaseStr = Console.ReadLine();
                        Console.ForegroundColor = ConsoleColor.White;
                    }

                    Console.ForegroundColor = ConsoleColor.White;

                    Console.Write("\n\nInclude Uppercase Letters (A - Z) [True], [False]: ");

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    string IncludeUppercaseStr = Console.ReadLine();
                    bool IncludeUppercase;

                    while (bool.TryParse(IncludeUppercaseStr, out IncludeUppercase) == false)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");

                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write("\nInclude Uppercase Letters (A - X) [True], [False]: ");

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        IncludeUppercaseStr = Console.ReadLine();
                        Console.ForegroundColor = ConsoleColor.White;
                    }

                    Console.ForegroundColor = ConsoleColor.White;

                    Console.Write("\n\nInclude Symbols [True], [False]: ");
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    string IncludeSymbolsStr = Console.ReadLine();
                    bool IncludeSymbols;

                    while (bool.TryParse(IncludeSymbolsStr, out IncludeSymbols) == false)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");

                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write("\nInclude Symbols [True], [False]: ");

                        Console.ForegroundColor = ConsoleColor.Yellow;
                        IncludeSymbolsStr = Console.ReadLine();
                        Console.ForegroundColor = ConsoleColor.White;
                    }

                    Console.ForegroundColor = ConsoleColor.White;

                    string Password = "";

                    while (Password.Length < Lenght)
                    {
                        Random Rand = new Random();

                        if (IncludeNumbers == true)
                        {
                            Password += ((char)Rand.Next(48, 58)).ToString();
                        }

                        if (Password.Length == Lenght)
                        {
                            break;
                        }

                        if (IncludeLowercase == true)
                        {
                            Password += ((char)Rand.Next(97, 123)).ToString();
                        }

                        if (Password.Length == Lenght)
                        {
                            break;
                        }

                        if (IncludeUppercase == true)
                        {
                            Password += ((char)Rand.Next(97, 123)).ToString().ToUpper();
                        }

                        if (Password.Length == Lenght)
                        {
                            break;
                        }

                        if (IncludeSymbols == true)
                        {
                            Password += ((char)Rand.Next(33, 48)).ToString().ToUpper();
                        }

                        if (Password.Length == Lenght)
                        {
                            break;
                        }
                    }

                    Password = Randomize(Password);

                    Console.WriteLine();

                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                    Console.WriteLine(Password);
                    Console.ForegroundColor = ConsoleColor.White;
                }

                else
                {
                    Environment.Exit(-1);
                }
            }

        }
    }
}

อยู่ที่221เส้นมากเกินไปสำหรับการนี้หรือไม่? วิธีการสวมใส่? นี่คือ "crapcode" หรือไม่ จะไม่เขียน crapcode ได้อย่างไร? .... ขอบคุณ!

คำตอบ

7 radarbob Sep 28 2020 at 10:52

จากเอกสาร MSDN Random class

ในการสร้างหมายเลขสุ่มที่ปลอดภัยด้วยการเข้ารหัสเช่นหมายเลขที่เหมาะสำหรับการสร้างรหัสผ่านแบบสุ่มให้ใช้คลาส RNGCryptoServiceProvider หรือรับคลาสจาก System.Security.Cryptography.RandomNumberGenerator


Random Rand = สุ่มใหม่ ();

แก้ไขการแก้ไข: การใช้สแน็ปช็อตของนาฬิการะบบตัวสร้างไม่มีพารามิเตอร์จะจบลงด้วยการใช้ค่าเมล็ดพันธุ์ที่แตกต่างกัน เว้นแต่ว่าวัตถุแบบสุ่มจะถูกสร้างขึ้นในเวลาใกล้เคียงกันจนใช้เวลานาฬิกาเดียวกัน ด้วยอาร์กิวเมนต์เดียวกัน (ค่าพารามิเตอร์เมล็ดพันธุ์) Randoms ที่แตกต่างกันจะสร้างลำดับแบบสุ่มเดียวกัน สิ้นสุดการแก้ไข

ทุก Randomออบเจ็กต์ที่สร้างด้วยคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์จะสร้างลำดับตัวเลขสุ่มเหมือนกันเนื่องจากมีการใช้ค่า "default seed" เดียวกันทุกครั้ง เหมาะสำหรับการพัฒนาและการทดสอบ แต่ไม่ใช่ในรหัสการผลิต การอ่านเวลาของระบบเป็นมิลลิวินาทีเป็นวิธีทั่วไปในการสร้างค่า "seed" ที่แตกต่างกันสำหรับการเรียกตัวสร้างแต่ละครั้ง


รหัสcrapcodeรหัสกลิ่น

ความสงสัยที่คลุมเครือเกี่ยวกับรหัสนี้เรียกในทางเทคนิคว่า "กลิ่นรหัส" ซึ่งหมายความว่ามันดูน่าสงสัยด้วยเหตุผลบางประการ - ความยาว "รู้สึก" โหยหาสิ่งที่กำลังทำอยู่ในกรณีนี้ อาจมีบางอย่างผิดปกติอาจจะไม่ "กลิ่นรหัส" ต้องการการตรวจสอบอย่างละเอียดถี่ถ้วนเพื่อตรวจสอบว่ามีสิ่งใดผิดจริงหรือไม่

กลิ่นรหัสที่ฉันเห็นคือwhileลูปที่มีลักษณะคล้ายกันหลายอันแต่ละอันกำลังมองหาอักขระที่ต้องการต่างกัน ฉันไม่ต้องการเขียนโค้ดให้เข้าใจยากเพราะจำนวนบรรทัดน้อยลง "โค้ดน้อยลง" เพียงอย่างเดียวไม่ใช่เหตุผลที่จะเปลี่ยนแปลงสิ่งต่างๆ นี่คือแนวคิดอาจเป็นการปรับปรุงหรืออาจจะไม่:

แจ้งให้ผู้ใช้ทราบถึงอักขระที่ต้องการล่วงหน้าเมื่อแจ้งให้ป้อนรหัสผ่าน

สตริงสามารถทำซ้ำได้คุณสามารถ "forEach" A Stringคืออาร์เรย์ของCharเทคนิคในทางเทคนิค

forEach (char character in enteredPassword) { ... }

ตรวจสอบอักขระแต่ละตัวสำหรับประเภทของมัน นับแยกต่างหากสำหรับอักขระแต่ละประเภท

หลังจากการforEachทดสอบแต่ละเคาน์เตอร์สำหรับขั้นต่ำที่ต้องการ symbolsตัวอย่างเช่นถ้าเป็นศูนย์ให้เพิ่ม "ต้องมีอักขระสัญลักษณ์อย่างน้อยหนึ่งตัว" ต่อท้ายข้อความแสดงข้อผิดพลาด


FYI

มีคำพูดเก่า ๆ ที่มีแก่นของความจริง: หากคุณแก้ปัญหาด้วยนิพจน์ทั่วไปตอนนี้คุณมีปัญหาสองประการ


221 บรรทัดมากเกินไปสำหรับสิ่งนี้

มีแนวทางหลักการ "isms" ฯลฯ มากมายสำหรับการประเมินคุณภาพโค้ด การนับเส้นไม่ใช่หนึ่งในนั้น