Home > Blockchain >  C# - Random method returns consecutively repeated values
C# - Random method returns consecutively repeated values

Time:09-23

I'll try to be brief, I think the code is quite simple. I'm trying to create a password generator using a starting string, containing all usable characters (ie "passwordChars") to be used in a FOR loop in association with the Random.Random method to randomly extract a character from the string and then recompose it in a new one to create the password.

private void GeneratePassword()
{
    string passwordChars = null;

    if (isMaiuscEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = "MNBVCXZLKJHGFDSAPOIUYTREWQ";
        }
        else
        {
            passwordChars  = "MNBVCXZLKJHGFDSAPOIUYTREWQ";
        }
    }

    if (isLowerEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = "alskdjfhgzmxncbvqpwoeiruty";
        }
        else
        {
            passwordChars  = "alskdjfhgzmxncbvqpwoeiruty";
        }
    }

    if (isNumberEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = "2674589103";
        }
        else
        {
            passwordChars  = "2674589103";
        }
    }

    if (isSymbolsEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = @"!()-.?[]_`~:;@#$%^&* =";
        }
        else
        {
            passwordChars  = @"!()-.?[]_`~:;@#$%^&* =";
        }
    }

    int passwordCharsLenght = passwordChars.Length;
    string password = null;

    for (int pwdLenght = 0; pwdLenght < int.Parse(PasswordSizeTextBox.Text); pwdLenght  )
    {
        Random randomizer = new Random();
        int charIndex = randomizer.Next(passwordCharsLenght);

        if (String.IsNullOrEmpty(password) == true)
        {
            password = passwordChars[charIndex].ToString();
        }
        else
        {
            password  = passwordChars[charIndex].ToString();
        }
    }

    PasswordOutputTextBlock.Text = password;
}

The problem is that in this way, the result will be a constant repetition of one or more characters, for example:

INPUTS:
Password size = 50, isUpperEnabled = true, isLowerEnabled = true,
isNumberEnabled = true, isSymbolsEnabled = true.

OUTPUT: 
AAAAAAAAAAAAAAAAAAAAAA3333333333333333333333333333

But if I add a MessageBox between the randomizer and the writing of the character obtained in the password strnga then everything works correctly, the password is generated perfectly never generating consecutive repetitions. The code with the inserted MessageBox:

private void GeneratePassword()
{
    string passwordChars = null;

    if (isMaiuscEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = "MNBVCXZLKJHGFDSAPOIUYTREWQ";
        }
        else
        {
            passwordChars  = "MNBVCXZLKJHGFDSAPOIUYTREWQ";
        }
    }

    if (isLowerEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = "alskdjfhgzmxncbvqpwoeiruty";
        }
        else
        {
            passwordChars  = "alskdjfhgzmxncbvqpwoeiruty";
        }
    }

    if (isNumberEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = "2674589103";
        }
        else
        {
            passwordChars  = "2674589103";
        }
    }

    if (isSymbolsEnabled == true)
    {
        if (string.IsNullOrEmpty(passwordChars) == true)
        {
            passwordChars = @"!()-.?[]_`~:;@#$%^&* =";
        }
        else
        {
            passwordChars  = @"!()-.?[]_`~:;@#$%^&* =";
        }
    }

    int passwordCharsLenght = passwordChars.Length;
    string password = null;

    for (int pwdLenght = 0; pwdLenght < int.Parse(PasswordSizeTextBox.Text); pwdLenght  )
    {
        Random randomizer = new Random();
        int charIndex = randomizer.Next(passwordCharsLenght);

        MessageBox.Show("STOP");

        if (String.IsNullOrEmpty(password) == true)
        {
            password = passwordChars[charIndex].ToString();
        }
        else
        {
            password  = passwordChars[charIndex].ToString();
        }
    }

    PasswordOutputTextBlock.Text = password;
}

I hope that I have been clear enough and that someone understands what I am doing wrong. Thanks in advance to everyone.

CodePudding user response:

I guess you are using an older .NET version. There the Random instance with the default constructor is using the current time as seed. To avoid repetions you have to move the initialization out of the loop, at the beginning of the method or even as static field:

private void GeneratePassword()
{
    Random randomizer = new Random();
    string passwordChars = null;

    // rest of method remains unchanged ...
}

It's also mentioned in the documentation:

they are instantiated using identical seed values based on the system clock and, therefore, they produce an identical sequence of random numbers

  • Related