Password issue in C#

Peter_1985 2,466 Reputation points
2022-05-14T06:31:16.99+00:00

Hi,
It does fall into the If condition below, when I have "H6666661_" as the value passed to it. Why?

        *var password = (value == null) ? string.Empty : value.ToString();
            var pattern = new Regex("((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})");
            if (!pattern.IsMatch(password))
            {*
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,246 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,203 questions
0 comments No comments
{count} votes

Accepted answer
  1. Lan Huang-MSFT 25,386 Reputation points Microsoft Vendor
    2022-05-16T06:29:06.623+00:00

    Hi @Peter_1985 ,
    You can refer to the following code, which is easier to understand when written separately.
    The length of the string must be between 8 and 15 characters. String must contain at least one number, at least one uppercase letter, at least one lowercase letter, and at least one special character.

     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;  
                }  
            }  
    

    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. P a u l 10,406 Reputation points
    2022-05-14T12:56:30.707+00:00

    It's not matching because the second group doesn't match the input string. The first one does (?=.*\d). This matches the start of the string, not the first character, because nothing precedes the opening parenthesis. It checks the pattern of anything followed by a digit, which matches H6666661 (without the underscore)

    The positive lookahead doesn't consume the characters it's looking ahead to, so it'll start from the beginning again with the next lookahead (?=.*[a-z]). This doesn't match because you're trying to match anything followed by a lowercase alphabetic character. Your sequence starts with an uppercase alphabetic character, but that's being matched against the .* (along with every proceeding character,) and there's no lowercase alphabetic character in the string at all.

    It's easier to test this with a regex evaluation tool like regex101.com to see what's going on: https://regex101.com/r/bvVDmh/1

    Also in your C# if you prefix your pattern string with @ then you don't have to escape any characters like you're doing with \\d, for example:

    new Regex(@"...
    

    That way you can copy between your code and regex101.com without having to remove the escape characters.