Chathz Chathz - 3 months ago 9
C# Question

Include a digit to automatically generate password

I'm using following code snippet to generate password automatically

string Password = Membership.GeneratePassword(12, 1);


but here sometimes its generating password without digit values then I'm getting following error


Passwords must have at least one digit ('0'-'9').


How can I upgrade above code to generate with digit value

Ian Ian
Answer

You can further process the generated password, if it doesn't contain a number, you randomly change one of them to a number like this:

if (!Password.Any(x => char.IsDigit(x))){
    Random rand = new Random();
    char[] pass = Password.ToCharArray();
    pass[rand.Next(Password.Length)] = Convert.ToChar(rand.Next(10) + '0');
    Password = new string(pass);
}

If you want to avoid for not having the lower character, you could add another check such as:

if (!Password.Any(x => char.IsLower(x))) {
    //Do similarly but using rand.Next(26) + 'a' instead of rand.Next(10) + '0'
}

And if you want to avoid the position that has been changed as a number to be the position you change as a lower character, simply store rand.Next(Password.Length) in the first number generation and avoid having the same value for the second.

Or, more robustly, we could define a List of nonSelectedIndexes and pick-and-remove a random number from it every time we perform a substitution operation:

List<int> nonSelectedIndexes = new List<int>(Enumerable.Range(0, Password.Length));
Random rand = new Random();

if (!Password.Any(x => char.IsDigit(x))) { //does not contain digit
    char[] pass = Password.ToCharArray();
    int pos = nonSelectedIndexes[rand.Next(nonSelectedIndexes.Count)];
    nonSelectedIndexes.Remove(pos);
    pass[pos] = Convert.ToChar(rand.Next(10) + '0');
    Password = new string(pass);
}

if (!Password.Any(x => char.IsLower(x))) { //does not contain lower
    char[] pass = Password.ToCharArray();
    int pos = nonSelectedIndexes[rand.Next(nonSelectedIndexes.Count)];
    nonSelectedIndexes.Remove(pos);
    pass[pos] = Convert.ToChar(rand.Next(26) + 'a');
    Password = new string(pass);
}

if (!Password.Any(x => char.IsUpper(x))) { //does not contain upper
    char[] pass = Password.ToCharArray();
    int pos = nonSelectedIndexes[rand.Next(nonSelectedIndexes.Count)];
    nonSelectedIndexes.Remove(pos);
    pass[pos] = Convert.ToChar(rand.Next(26) + 'A');
    Password = new string(pass);
}

//And so on
//Do likewise to any other condition 

Note: Please consider Mr. SilverlightFox comment if you use this for anything security-related.

Comments