パスワードジェネレータ「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行が多すぎますか?それを強制する方法は?これは「クラップコード」ですか?どうやってクラップコードを書かないのですか?....ありがとう!

回答

7 radarbob Sep 28 2020 at 10:52

以下からのMSDNランダムクラスのドキュメント

ランダムパスワードの作成に適したものなど、暗号で保護された乱数を生成するには、RNGCryptoServiceProviderクラスを使用するか、System.Security.Cryptography.RandomNumberGeneratorからクラスを派生させます。


Random Rand = new Random();

編集の修正:システムクロックのスナップショットを使用すると、パラメーターなしのコンストラクターは異なるシード値を使用することになります。ランダムオブジェクトが非常に近い時間に作成され、同じ時刻が使用されない限り。同じ引数(パラメーターシード値)が与えられると、異なるランダムは同じランダムシーケンスを生成します。編集終了

Randomパラメータなしのコンストラクタで作成された すべてのオブジェクトは、毎回 同じ「デフォルトシード」値が使用されるため、同じ乱数シーケンスを生成します。これは開発とテストには最適ですが、本番コードには最適ではありません。システム時間をミリ秒単位で読み取ることは、コンストラクター呼び出しごとに異なる「シード」値を生成する一般的な方法です。


crapcode コードの臭い

コードについてのあいまいな疑問は、技術的には「コードの臭い」と呼ばれます。つまり、何らかの理由で疑わしいように見えます。この場合、長さはコードの動作に対して長く「感じ」ます。何か問題があるかもしれませんが、そうではないかもしれません。「コードの臭い」は、何かが実際に間違っているかどうかを判断するために、より綿密な調査を必要とします。

私が見るコードの臭いはwhile、それぞれが異なる必要な文字を探している、複数の似たようなループです。行数を減らすために、わかりにくいコードを書きたくありません。「コードの行数が少ない」だけでは、状況を変える理由にはなりません。ここにアイデアがあります、多分それは改善であるかそうでないかもしれません:

パスワードの入力を求めるときは、事前に必要な文字をユーザーに伝えてください。

文字列は反復可能であり、「forEach」を実行できます。AStringは実際Char、技術的にはの配列です。

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

各文字のタイプを調べます。文字タイプごとに個別のカウントを保持します。

forEachテスト後、各カウンターで必要な最小値を確認します。symbolsたとえば、がゼロの場合、エラーメッセージに「少なくとも1つの記号文字が必要です」を追加します。


ご参考までに

真実の核心を持つ古いことわざがあります:正規表現で問題を解決する場合、今あなたは2つの問題を抱えています


これには221行が多すぎますか

コードの品質を評価するためのガイドライン、原則、「主義」などはたくさんあります。行数はそれらの1つではありません。