Regular Expression for strong password in MVC model

10,555

Solution 1

Creating a regex that will find any number of different kinds of character classes in any order is a little challenging because as soon as you match a character, it's already captured and you can't back it up. However, the .NET regex engine supports lookahead expressions. Therefore, you can check to make sure that a string contains something without actually capturing any of the string. For instance, let's say that you want to find any 10 character long string that contains at least one instance of the letter "J". You could do that easily with a lookahead expression, like this:

(?=.*J).{10}

The (?=) construct declares a lookahead pattern. The pattern it looks for is .*J, which means that, starting at the current position, there can be any number of any character followed by a letter "J". If anything comes after the J, that's fine, it will still match. However, since it's a lookahead, none of those characters were actually captured, so then the .{10} capturing part of the pattern picks up from the original position and matches from there. Since the lookaheads don't move the position at all, you can put multiple of them in a row without consequence, so you can do something like this:

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

As far as applying only three of the four character class rules, the only way I can think of to do that would be to list all of the combinations (e.g. for two of the three rules A, B, and C, you could match AB|AC|BC) . So for instance, if you were only concerned with two of the three (uppercase, lowercase, and digits, for instance), you could structure your lookaheads like this:

(?:(?=.*[A-Z])(?=.*\d)|(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[a-z]))

Making it support there out of four would just be a matter of making the list of options even longer...

Solution 2

A development of Steven's answer would be to test for all possible combinations of the types:

^((?=.*[A-Z])(?=.*\d)(?=.*[a-z])|(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%&\/=?_.-])|(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%&\/=?_.-])|(?=.*\d)(?=.*[a-z])(?=.*[!@#$%&\/=?_.-])).{7,15}$

Also using the given special characters.

In a more readable form

^((?=.*[A-Z])(?=.*\d)(?=.*[a-z])|
(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%&\/=?_.-])|
(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%&\/=?_.-])|
(?=.*\d)(?=.*[a-z])(?=.*[!@#$%&\/=?_.-])).{7,15}$

Test for either of the possible four combinations of types and make sure there are 7-14 of them.

Regards

Share:
10,555
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I need to create a regular expression to validate a strong password in my MVC Model. Here are the rules that I need to apply:

    • Min 7 characters
    • Max 15 characters
    • At least 3 out of 4 different types of characters.
      • Numbers
      • Lowercase
      • Uppercase
      • Special (viz. !@#$%&/=?_.)

    Here's what I have tried so far:

    [DataType(DataType.Password)]
    [RegularExpression("([a-z]|[A-Z]|[0-9]|[\\W]){4}[a-zA-Z0-9\\W]{3,11}", ErrorMessage = "Invalid password format")]        
    public string Password { get; set; }