using System.Text.RegularExpressions;
using CodeShare.Library.Passwords;
public static void Main()
bool includeLowercase = true;
bool includeUppercase = true;
bool includeNumeric = true;
bool includeSpecial = false;
bool includeSpaces = false;
int lengthOfPassword = 16;
string password = PasswordGenerator.GeneratePassword(includeLowercase, includeUppercase, includeNumeric, includeSpecial, includeSpaces, lengthOfPassword);
while(!PasswordGenerator.PasswordIsValid(includeLowercase, includeUppercase, includeNumeric, includeSpecial, includeSpaces, password))
password = PasswordGenerator.GeneratePassword(includeLowercase, includeUppercase, includeNumeric, includeSpecial, includeSpaces, lengthOfPassword);
Console.WriteLine(password);
namespace CodeShare.Library.Passwords
public static class PasswordGenerator
public static string GeneratePassword(bool includeLowercase, bool includeUppercase, bool includeNumeric, bool includeSpecial, bool includeSpaces, int lengthOfPassword)
const int MAXIMUM_IDENTICAL_CONSECUTIVE_CHARS = 2;
const string LOWERCASE_CHARACTERS = "abcdefghijklmnopqrstuvwxyz";
const string UPPERCASE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string NUMERIC_CHARACTERS = "0123456789";
const string SPECIAL_CHARACTERS = @"!#$%&*@\";
const string SPACE_CHARACTER = " ";
const int PASSWORD_LENGTH_MIN = 8;
const int PASSWORD_LENGTH_MAX = 128;
if (lengthOfPassword < PASSWORD_LENGTH_MIN || lengthOfPassword > PASSWORD_LENGTH_MAX)
return "Password length must be between 8 and 128.";
string characterSet = "";
characterSet += LOWERCASE_CHARACTERS;
characterSet += UPPERCASE_CHARACTERS;
characterSet += NUMERIC_CHARACTERS;
characterSet += SPECIAL_CHARACTERS;
characterSet += SPACE_CHARACTER;
char[] password = new char[lengthOfPassword];
int characterSetLength = characterSet.Length;
System.Random random = new System.Random();
for (int characterPosition = 0; characterPosition < lengthOfPassword; characterPosition++)
password[characterPosition] = characterSet[random.Next(characterSetLength - 1)];
bool moreThanTwoIdenticalInARow =
characterPosition > MAXIMUM_IDENTICAL_CONSECUTIVE_CHARS
&& password[characterPosition] == password[characterPosition - 1]
&& password[characterPosition - 1] == password[characterPosition - 2];
if (moreThanTwoIdenticalInARow)
return string.Join(null, password);
public static bool PasswordIsValid(bool includeLowercase, bool includeUppercase, bool includeNumeric, bool includeSpecial, bool includeSpaces, string password)
const string REGEX_LOWERCASE = @"[a-z]";
const string REGEX_UPPERCASE = @"[A-Z]";
const string REGEX_NUMERIC = @"[\d]";
const string REGEX_SPECIAL = @"([!#$%&*@\\])+";
const string REGEX_SPACE = @"([ ])+";
bool lowerCaseIsValid = !includeLowercase || (includeLowercase && Regex.IsMatch(password, REGEX_LOWERCASE));
bool upperCaseIsValid = !includeUppercase || (includeUppercase && Regex.IsMatch(password, REGEX_UPPERCASE));
bool numericIsValid = !includeNumeric || (includeNumeric && Regex.IsMatch(password, REGEX_NUMERIC));
bool symbolsAreValid = !includeSpecial || (includeSpecial && Regex.IsMatch(password, REGEX_SPECIAL));
bool spacesAreValid = !includeSpaces || (includeSpaces && Regex.IsMatch(password, REGEX_SPACE));
return lowerCaseIsValid && upperCaseIsValid && numericIsValid && symbolsAreValid && spacesAreValid;