Генератор паролей «Crapcode»

Sep 27 2020

Я сделал Генератор паролей на 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

Чтобы сгенерировать криптографически безопасное случайное число, например, подходящее для создания случайного пароля, используйте класс RNGCryptoServiceProvider или наследовать класс от System.Security.Cryptography.RandomNumberGenerator.


Случайный ранд = новый Случайный ();

Исправление при редактировании : используя снимок системных часов, конструктор без параметров использует разные начальные значения; если только объекты Random не созданы настолько близко по времени, что используется то же время часов. Учитывая один и тот же аргумент (начальное значение параметра), разные рандомы генерируют одну и ту же случайную последовательность. конец Править

Каждый Randomобъект, созданный с помощью конструктора без параметров, будет генерировать одну и ту же последовательность случайных чисел, поскольку каждый раз используется одно и то же «начальное значение по умолчанию». Это идеально подходит для разработки и тестирования, но не для производственного кода. Считывание системного времени в миллисекундах - это обычный способ генерировать разные «начальные» значения для каждого вызова конструктора.


crapcode Код Запах

Нечеткие сомнения, которые у вас возникают по поводу кода, технически называются «запахом кода», то есть по какой-то причине они выглядят подозрительно - в данном случае длина «кажется» длинной для того, что он делает. Может что-то не так, а может и нет; "запах кода" требует более тщательного изучения, чтобы определить, действительно ли что-то не так.

Запах кода, который я вижу, - это несколько похожих whileциклов, каждый из которых ищет разные необходимые символы. Я не хочу писать сложный для понимания код ради меньшего количества строк. Само по себе «меньшее количество строк кода» еще не повод что-то менять. Вот идея, может быть, это улучшение, а может, и нет:

Сообщите пользователю необходимые символы при запросе пароля.

Строка может повторяться, вы можете "forEach". StringФактически Char, технически A - это массив файлов.

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

Изучите каждый символ на предмет его типа. Ведите отдельный счет для каждого типа символов.

После forEachпроверки каждый счетчик на необходимый минимум. Если symbols, например, равно нулю, добавьте к сообщению об ошибке «хотя бы один символ символа».


К вашему сведению

Есть старая поговорка, в основе которой лежит истина: если вы решите проблему с помощью регулярного выражения, теперь у вас есть две проблемы.


221 строка слишком много для этого

Существует множество руководств, принципов, «измов» и т. Д. Для оценки качества кода. Количество строк не входит в их число.