4

I'm looking to do some pattern matching for passwords, and found a regex example on SO, but when I pass a password through which should be deemed "strong", I am met with the opposite. For example, the string "JlcimYQF+EkHVA*" yields a rating of 1, which means that the string patterns aren't being matched in the regex, but I am unsure why.

Code below:

public class PasswordAdvisor
{
    public static PasswordScore CheckStrength(string password)
    {
        int score = 1;

        if (password.Length < 12)
            return PasswordScore.TooShort;
        if (password.Length >= 16)
            score++;
        if (Regex.Match(password, @"/\d+/", RegexOptions.ECMAScript).Success)
            score++;
        if (Regex.Match(password, @"/[a-z]/", RegexOptions.ECMAScript).Success &&
          Regex.Match(password, @"/[A-Z]/", RegexOptions.ECMAScript).Success)
            score++;
        if (Regex.Match(password, @"/.[!,@,#,$,%,^,&,*,?,_,~,-,£,(,)]/", RegexOptions.ECMAScript).Success)
            score++;

        return (PasswordScore)score;
    }
}

Deceleration:

var passwordStrengthScore = PasswordAdvisor.CheckStrength(@"JlcimYQF+EkH*VA");

        Console.WriteLine((int)passwordStrengthScore);

        switch (passwordStrengthScore)
        {
            case PasswordScore.TooShort:
                Console.WriteLine("Password is too short");
                break;
            case PasswordScore.Weak:
                Console.WriteLine("Password is very weak");
                break;
            case PasswordScore.Medium:
                Console.WriteLine("OK password");
                break;
            case PasswordScore.Strong:
                Console.WriteLine("Strong password");
                break;
            case PasswordScore.VeryStrong:
                Console.WriteLine("Very strong password");
                break;
        }
2
  • 4
    Remove / delimiters from all patterns. Replace @"/.[!,@,#,$,%,^,&,*,?,_,~,-,£,(,)]/" with @"[!,@#$%^&*?_~£()-]" to also require one of these special chars. In all but Regex.Match(password, @"\d+", RegexOptions.ECMAScript) statements, you may safely remove RegexOptions.ECMAScript option. Commented Jun 22, 2018 at 10:51
  • Ok, I added the answer to provide more insight. Commented Jun 22, 2018 at 10:59

1 Answer 1

3

You should remove / delimiters from all patterns as .NET regexes are defined with string literals, no delimiters are required, and these / chars are part of the patterns that do not match what you expect.

You should replace @"/.[!,@,#,$,%,^,&,*,?,_,~,-,£,(,)]/" with @"[!,@#$%^&*?_~£()-]" to require at least one of these special chars. Note that an unescaped - inside a character class between literals creates a range, thus it is safer to put it at the end (or escape it). NOTE: I kept the comma inside, but since you used it as an OR operator, probably, you should remove it completely. The OR relationship is the default one between atoms in a positive character class.

In all but Regex.Match(password, @"\d+", RegexOptions.ECMAScript) statements, you may safely remove RegexOptions.ECMAScript option that only affects shorthand character class (like \s, \d, etc.).

Use

    if (Regex.Match(password, @"\d+", RegexOptions.ECMAScript).Success)
        score++;
    if (Regex.Match(password, @"[a-z]").Success &&
      Regex.Match(password, @"[A-Z]").Success)
        score++;
    if (Regex.Match(password, @"[!,@#$%^&*?_~£()-]").Success) // check if you need a comma here
        score++;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.