Regular Expression for password validation

C#.NetRegex

C# Problem Overview


I currently use this regular expression to check if a string conforms to a few conditions.

The conditions are string must be between 8 and 15 characters long. string must contain at least one number. string must contain at least one uppercase letter. string must contain at least one lowercase letter.

(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,15})$

It works for the most part, but it does not allow special character. Any help modifying this regex to allow special character is much appreciated.

C# Solutions


Solution 1 - C#

There seems to be a lot of confusion here. The answers I see so far don't correctly enforce the 1+ number/1+ lowercase/1+ uppercase rule, meaning that passwords like abc123, 123XYZ, or AB&^#* would still be accepted. Preventing all-lowercase, all-caps, or all-digits is not enough; you have to enforce the presence of at least one of each.

Try the following:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,15}$

If you also want to require at least one special character (which is probably a good idea), try this:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$

The .{8,15} can be made more restrictive if you wish (for example, you could change it to \S{8,15} to disallow whitespace), but remember that doing so will reduce the strength of your password scheme.

I've tested this pattern and it works as expected. Tested on ReFiddle here: http://refiddle.com/110


Edit: One small note, the easiest way to do this is with 3 separate regexes and the string's Length property. It's also easier to read and maintain, so do it that way if you have the option. If this is for validation rules in markup, though, you're probably stuck with a single regex.

Solution 2 - C#

Is a regular expression an easier/better way to enforce a simple constraint than the more obvious way?

static bool ValidatePassword( string password )
{
  const int MIN_LENGTH =  8 ;
  const int MAX_LENGTH = 15 ;

  if ( password == null ) throw new ArgumentNullException() ;

  bool meetsLengthRequirements = password.Length >= MIN_LENGTH && password.Length <= MAX_LENGTH ;
  bool hasUpperCaseLetter      = false ;
  bool hasLowerCaseLetter      = false ;
  bool hasDecimalDigit         = false ;

  if ( meetsLengthRequirements )
  {
    foreach (char c in password )
    {
      if      ( char.IsUpper(c) ) hasUpperCaseLetter = true ;
      else if ( char.IsLower(c) ) hasLowerCaseLetter = true ;
      else if ( char.IsDigit(c) ) hasDecimalDigit    = true ;
    }
  }

  bool isValid = meetsLengthRequirements
              && hasUpperCaseLetter
              && hasLowerCaseLetter
              && hasDecimalDigit
              ;
  return isValid ;

}

Which do you think that maintenance programmer 3 years from now who needs to modify the constraint will have an easier time understanding?

Solution 3 - C#

You may try this method:

    private bool ValidatePassword(string password, out string ErrorMessage)
        {
            var input = password;
            ErrorMessage = string.Empty;

            if (string.IsNullOrWhiteSpace(input))
            {
                throw new Exception("Password should not be empty");
            }

            var hasNumber = new Regex(@"[0-9]+");
            var hasUpperChar = new Regex(@"[A-Z]+");
            var hasMiniMaxChars = new Regex(@".{8,15}");
            var hasLowerChar = new Regex(@"[a-z]+");
            var hasSymbols = new Regex(@"[!@#$%^&*()_+=\[{\]};:<>|./?,-]");

            if (!hasLowerChar.IsMatch(input))
            {
                ErrorMessage = "Password should contain at least one lower case letter.";
                return false;
            }
            else if (!hasUpperChar.IsMatch(input))
            {
                ErrorMessage = "Password should contain at least one upper case letter.";
                return false;
            }
            else if (!hasMiniMaxChars.IsMatch(input))
            {
                ErrorMessage = "Password should not be lesser than 8 or greater than 15 characters.";
                return false;
            }
            else if (!hasNumber.IsMatch(input))
            {
                ErrorMessage = "Password should contain at least one numeric value.";
                return false;
            }

            else if (!hasSymbols.IsMatch(input))
            {
                ErrorMessage = "Password should contain at least one special case character.";
                return false;
            }
            else
            {
                return true;
            }
        }

Solution 4 - C#

Update to Justin answer above. if you want to use it using Data Annotation in MVC you can do as follow

[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$", ErrorMessage = "Password must be between 6 and 20 characters and contain one uppercase letter, one lowercase letter, one digit and one special character.")]

Solution 5 - C#

I would check them one-by-one; i.e. look for a number \d+, then if that fails you can tell the user they need to add a digit. This avoids returning an "Invalid" error without hinting to the user whats wrong with it.

Solution 6 - C#

Try this ( also corrected check for upper case and lower case, it had a bug since you grouped them as [a-zA-Z] it only looks for atleast one lower or upper. So separated them out ):

(?!^[0-9]*$)(?!^[a-z]*$)(?!^[A-Z]*$)^(.{8,15})$

Update: I found that the regex doesn't really work as expected and this is not how it is supposed to be written too!

Try something like this:

(?=^.{8,15}$)(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?!.*\s).*$

(Between 8 and 15 inclusive, contains atleast one digit, atleast one upper case and atleast one lower case and no whitespace.)

And I think this is easier to understand as well.

Solution 7 - C#

Long, and could maybe be shortened. Supports special characters ?"-_.

\A(?=[-\?\"_a-zA-Z0-9]*?[A-Z])(?=[-\?\"_a-zA-Z0-9]*?[a-z])(?=[-\?\"_a-zA-Z0-9]*?[0-9])[-\?\"_a-zA-Z0-9]{8,15}\z

Solution 8 - C#

Thanks Nicholas Carey. I was going to use regex first but what you wrote changed my mind. It is so much easier to maintain this way.

//You can set these from your custom service methods
int minLen = 8;
int minDigit 2;
int minSpChar 2;

Boolean ErrorFlag = false;
//Check for password length
if (model.NewPassword.Length < minLen)
{
	ErrorFlag = true;
	ModelState.AddModelError("NewPassword", "Password must be at least " + minLen + " characters long.");
}

//Check for Digits and Special Characters
int digitCount = 0;
int splCharCount = 0;
foreach (char c in model.NewPassword)
{
	if (char.IsDigit(c)) digitCount++;
	if (Regex.IsMatch(c.ToString(), @"[!#$%&'()*+,-.:;<=>?@[\\\]{}^_`|~]")) splCharCount++;
}

if (digitCount < minDigit)
{
	ErrorFlag = true;
	ModelState.AddModelError("NewPassword", "Password must have at least " + minDigit + " digit(s).");
}
if (splCharCount < minSpChar)
{
	ErrorFlag = true;
	ModelState.AddModelError("NewPassword", "Password must have at least " + minSpChar + " special character(s).");
}

if (ErrorFlag)
	return View(model);

Solution 9 - C#

Pattern satisfy, these below criteria

  1. Password Length 8 and Maximum 15 character
  2. Require Unique Chars
  3. Require Digit
  4. Require Lower Case
  5. Require Upper Case
^(?!.*([A-Za-z0-9]))(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,15}$

Solution 10 - C#

^^(?=.*[A-Z]{"+minUpperCase+",})(?=.*[a-z]{"+minLowerCase+",})(?=.*[0-9]{"+minNumerics+",})(?=.*[!@#$\-_?.:{]{"+minSpecialChars+",})[a-zA-Z0-9!@#$\-_?.:{]{"+minLength+","+maxLength+"}$

Solution 11 - C#

I have modified @Anurag's answer in other question to meet my requirement:

Needed the method to return a list showing where password failed to meet my policy, so first created an Enum with all possible issues:

public enum PasswordPolicyIssue
{
        MustHaveNumber,
        MustHaveCapitalLetter,
        MustHaveSmallLetter,
        MustBeAtLeast8Characters,
        MustHaveSymbol
}

Then the validation method, that returns bool and has an output List:

public bool MeetsPasswordPolicy(string password, out List<PasswordPolicyIssue> issues)
{
        var input = password;
        issues = new List<PasswordPolicyIssue>();

        if (string.IsNullOrWhiteSpace(input))
            throw new Exception("Password should not be empty");

        var hasNumber = new Regex(@"[0-9]+");
        var hasUpperChar = new Regex(@"[A-Z]+");
        //var hasMiniMaxChars = new Regex(@".{8,15}");
        var hasMinChars = new Regex(@".{8,}");
        var hasLowerChar = new Regex(@"[a-z]+");
        var hasSymbols = new Regex(@"[!@#$%^&*()_+=\[{\]};:<>|./?,-]");

        if (!hasLowerChar.IsMatch(input))
            issues.Add(PasswordPolicyIssue.MustHaveSmallLetter);

        if (!hasUpperChar.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustHaveCapitalLetter);

        if (!hasMinChars.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustBeAtLeast8Characters);

        if (!hasNumber.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustHaveNumber);

        if (!hasSymbols.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustHaveSymbol);
        
        return issues.Count() ==0;
}

Original answer by @Anurag

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondesiView Question on Stackoverflow
Solution 1 - C#Justin MorganView Answer on Stackoverflow
Solution 2 - C#Nicholas CareyView Answer on Stackoverflow
Solution 3 - C#AnuragView Answer on Stackoverflow
Solution 4 - C#M HanifView Answer on Stackoverflow
Solution 5 - C#Alex K.View Answer on Stackoverflow
Solution 6 - C#manojldsView Answer on Stackoverflow
Solution 7 - C#Ken WhiteView Answer on Stackoverflow
Solution 8 - C#MaxView Answer on Stackoverflow
Solution 9 - C#MayankGaurView Answer on Stackoverflow
Solution 10 - C#Ashwin H AView Answer on Stackoverflow
Solution 11 - C#iYazee6View Answer on Stackoverflow