This is an update for a post that I wrote back in 2010 on how to generate a password using VB.NET. The overall design of the code has been kept the same although I have made a few adjustments according to things that I have learnt since I wrote the original code, like the use of a StringBuilder instead of just concatenating strings to build up the allowed character set.

### Generate password from character set

I decided to first create a method that would given a character set and a specified number of characters would produce a password.

private static readonly Random Rand = new Random();

{
if (String.IsNullOrEmpty(characterSet))
{
throw new ArgumentNullException("characterSet",
"The characterSet parameter must not be null or an empty string");
}

{
throw new ArgumentException("The password length must be greater than zero",
}

var sb = new StringBuilder();
int characterSetLength = characterSet.Length;

for (int i = 0; i < passwordLength; i++)
{
sb.Append(characterSet.Substring(Rand.Next(0, characterSetLength),1));
}

return sb.ToString();
}


At the beginning of the method I ensured that the character set has characters in it and that the requested password length is greater than zero. This uses a static instance of the Random class to choose a random character from the character set, please note that the instance is created outside of the method and is initialised only once, for an explanation of why I did this please see the post I wrote about the correct use of the Random class.

### Generating the character set from a set of options

Rather than requiring the user to identify the characters in a character set, I created a method that would by specifying a few options about what character types could be included in the password and a password length would generate a password.

public static string GeneratePassword(int passwordLength = 16,
bool includeUpperCase = true,
bool includeNumbers = true,
bool includeSymbols = true,
bool includeSimilarCharacters = true)
{
{
throw new ArgumentException("The password length must be greater than zero",
}

var allowedCharacters = new StringBuilder();

// Lower case characters
allowedCharacters.Append("abcdefghijkmnopqrstuvwxyz");
if (includeSimilarCharacters)
{
allowedCharacters.Append("l");
}

// Upper case characters
if (includeUpperCase)
{
allowedCharacters.Append("ABCDEFGHJKLMNPQRSTUVWXYZ");
if (includeSimilarCharacters)
{
allowedCharacters.Append("IO");
}
}

// Numbers
if (includeNumbers)
{
allowedCharacters.Append("23456789");
if (includeSimilarCharacters)
{
allowedCharacters.Append("10");
}
}

// Symbols
if (includeSymbols)
{
allowedCharacters.Append("|\$%^&*()_+~-=#[]{};':@,./<>?");
if (includeSimilarCharacters)
{
allowedCharacters.Append("!");
}
}