0

I programmed this in C# in a console application.

So I wanted to create a random password generator and I basically succeeded, however, I encountered an error I can't quite understand.

Printing just 1 password isn't a problem. However, when I want to print multiple passwords at once, with for example a for loop that runs until it hits 15, all the passwords printed are the same. However when I write Console.ReadLine() in the for loop to basically manually continue the for loop, one password after the other is printed and they are all different.

The complete code is down there. I appreciate any help.

static void Main(string[] args)
{
    for (int i = 0; i < 15; i++)
    {
        char[] alphabetUpper = GenerateCharacters(65, 91);
        char[] alphabetLower = GenerateCharacters(98, 124);
        int[] numbers = GenerateNumbers(47, 57);
        char[] specialCharacters = GenerateCharacters(34, 40);
        string password = CreatePassword(alphabetUpper, alphabetLower, specialCharacters, numbers);
        Console.WriteLine(password);
    }
    // Here I encounter the described problem. When I put the Console.ReadLine() in the for loop, it works normally though.
    Console.ReadLine();
}

// Generates characters with the numbers from the GenerateNumbers method by casting them.
static char[] GenerateCharacters(int lowerBorder, int upperBorder)
{
    int[] numberArray = GenerateNumbers(lowerBorder, upperBorder);
    char[] charArray = new char[100];
    for (int i = 0; i < numberArray.Length; i++)
    {
        charArray[i] = (char)numberArray[i];
    }
    return charArray;
}

// Upper and lower border of the numbers to ensure, that when the numbers are needed for characters, that only the wanted characters will be cast.
static int[] GenerateNumbers(int lowerBorder, int upperBorder)
{
    Random rng = new Random();
    int[] numberArray = new int[100];
    for (int i = 0; i < 98; i++)
    {
        int number = rng.Next(lowerBorder, upperBorder);
        numberArray[i] = number;
    }
    return numberArray;
}

static string CreatePassword(char[] alphabetUpper, char[] specialCharacters, char[] alphabetLower, int[] randomNumbers)
{
    var rng = new Random();
    int passwordLength = rng.Next(3, alphabetUpper.Length);
    var passwordCharacters = new char[passwordLength];
    var password = string.Empty;

    for (int i = 0; i < passwordLength; i++)
    {
        int whichArray = rng.Next(0, 4);
        int randomIndex = rng.Next(0, 100);

        if (whichArray == 0)
        {
            passwordCharacters[i] = alphabetUpper[randomIndex];
        }
        else if (whichArray == 1)
        {
            passwordCharacters[i] = specialCharacters[randomIndex];
        }
        else if (whichArray == 2)
        {
            passwordCharacters[i] = alphabetLower[randomIndex];
        }
        else
        {
            passwordCharacters[i] = (char)randomNumbers[randomIndex];
        }
    }

    for (int i = 0; i < passwordCharacters.Length; i++)
    {
        password += passwordCharacters[i];
    }

    return password;
}
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Patai
  • 63
  • 5
  • 2
    You've fallen into the problem of recreating `Random` in a tight loop. The seed is the current `DateTime` which might not change in the amount of time it takes the loop to run thus giving you identical random numbers, or worse in your case the same sequence of random numbers. Try making `rng` a static field that is initialized once. – juharr Nov 07 '17 at 19:07
  • Have a look at https://stackoverflow.com/questions/10903613/using-clock-ticks-as-random-number-seed – d219 Nov 07 '17 at 19:10
  • Look at `RNGCryptoServiceProvider`, that will help u – Frank Nielsen Nov 07 '17 at 19:16
  • If you had looked up Random on MSDN you could have read the warning for just this sort of thing. – Ňɏssa Pøngjǣrdenlarp Nov 07 '17 at 21:37

0 Answers0