Generator haseł „Crapcode”

Sep 27 2020

Stworzyłem Generator haseł na C #.

Pyta użytkownika o długość hasła , niezależnie od tego , czy zawiera cyfry , małe litery , wielkie litery czy symbole , i generuje silne hasło z losowo dodanych cyfr, liter lub symboli.

Oto kod:

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);
                }
            }

        }
    }
}

Czy 221 linii to za dużo? Jak to ulepszyć? Czy to jest "crapcode"? Jak nie pisać crapcode? ....Dzięki!

Odpowiedzi

7 radarbob Sep 28 2020 at 10:52

Z dokumentacji klasy MSDN Random

Aby wygenerować bezpieczną kryptograficznie liczbę losową, na przykład odpowiednią do tworzenia losowego hasła, użyj klasy RNGCryptoServiceProvider lub wyprowadź klasę z System.Security.Cryptography.RandomNumberGenerator.


Random Rand = nowy Random ();

Korekta edycji : Używając migawki zegara systemowego, konstruktor bez parametrów kończy używanie różnych wartości początkowych; chyba że obiekty Random są tworzone tak blisko w czasie, że używany jest ten sam czas zegara. Mając ten sam argument (wartość inicjatora parametru), różne Randoms generują tę samą losową sekwencję. koniec Edytuj

Każdy Randomobiekt utworzony za pomocą konstruktora bezparametrowego wygeneruje tę samą sekwencję liczb losowych, ponieważ za każdym razem używana jest ta sama wartość „domyślnego ziarna”. Jest to idealne rozwiązanie do programowania i testowania, ale nie w kodzie produkcyjnym. Odczytywanie czasu systemowego w milisekundach jest powszechnym sposobem generowania różnych wartości „ziarna” dla każdego wywołania konstruktora.


kod crapcode Zapach

Rozmyte wątpliwości co do kodu są technicznie nazywane „zapachem kodu”, co oznacza, że ​​z jakiegoś powodu wygląda on podejrzanie - w tym przypadku „wydaje się” zbyt długi. Może coś jest nie tak, może nie; „zapach kodu” wymaga dokładniejszej analizy, aby ustalić, czy coś jest w rzeczywistości nie tak.

Zapach kodu, który widzę, to wiele podobnie wyglądających whilepętli, z których każda szuka innych wymaganych znaków. Nie chcę pisać trudnego do zrozumienia kodu ze względu na mniejszą liczbę wierszy. Samo „mniej linii kodu” nie jest powodem do zmiany. Oto pomysł, może to poprawa, a może nie:

Po wyświetleniu prośby o hasło podaj użytkownikowi wymagane znaki z góry.

Łańcuch jest iterowalny, możesz "forEach". Technicznie rzecz biorąc, A Stringjest w rzeczywistości tablicą Char.

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

Zbadaj każdy znak pod kątem jego typu. Zachowaj osobną liczbę dla każdego typu znaków.

Po forEachteście każdy licznik dla wymaganego minimum. symbolsNa przykład, jeśli wynosi zero, do komunikatu o błędzie należy dołączyć „co najmniej jeden znak symbolu”.


FYI

Jest takie stare powiedzenie z rdzeniem prawdy: jeśli rozwiązujesz problem za pomocą wyrażenia regularnego, masz teraz dwa problemy


221 linii za dużo na to

Istnieje wiele wskazówek, zasad, „izmów” itp. Dotyczących oceny jakości kodu. Liczba linii nie jest jedną z nich.