10

This must be simple and I expect it working in the same way but it's not helping me out.

using System;
using System.Text.RegularExpressions;

I am in a need of password validation regular expression with certain conditions where -

1) It must contain at least a number

2) one upper case letter

3) 8 characters long.

public class Program
{
     public static bool IsValidPassword(string plainText) {
            Regex regex = new Regex(@"^(.{0,7}|[^0-9]*|[^A-Z])$");
            Match match = regex.Match(plainText);
            return match.Success;
}
    public static void Main()
    {
        Console.WriteLine(IsValidPassword("shing"));    //logs 'True' always
    }
}

I've taken regex from this source- Password must be 8 characters including 1 uppercase letter, 1 special character, alphanumeric characters

Issue is that it returns 'True' always and the string that I am sending to method is not valid.

Help me if I am doing something wrong with the regex.

Please play with it here- https://dotnetfiddle.net/lEFYGJ

Community
  • 1
  • 1
Manoz
  • 6,507
  • 13
  • 68
  • 114

6 Answers6

43

I recommend you create separate patterns to validate the password:

var input = "P@ssw0rd";

var hasNumber = new Regex(@"[0-9]+");
var hasUpperChar = new Regex(@"[A-Z]+");
var hasMinimum8Chars = new Regex(@".{8,}");

var isValidated = hasNumber.IsMatch(input) && hasUpperChar.IsMatch(input) && hasMinimum8Chars.IsMatch(input);
Console.WriteLine(isValidated);
tdat00
  • 810
  • 1
  • 8
  • 11
  • 10
    I don't understand the people trying to push all this into one monster regex when this solution is so short and concise and readable. This is DEFINATELY the way to go imo. – sara Jan 11 '16 at 07:04
  • 2
    If you are in for splitting the checks, why use regex at all? A regex can be used here to implement all the 3 requirements that will make code shorter and faster - if written correctly. – Wiktor Stribiżew Jan 11 '16 at 07:41
  • 3
    @stribizhev: the point is *if written correctly*. After 1 month, you will forgot most of code you wrote. It will take you a lot of time to understand the messy regex than that simpler code. – tdat00 Jan 11 '16 at 07:43
  • 1
    What regex do you consider messy? `^(?=\D*\d)(?=\P{Lu}*\p{Lu}).{8}$`? Where is it messy? It is clear as rain. See [*Lookahead Example: Simple Password Validation*](http://www.rexegg.com/regex-lookarounds.html#password) if you ever have any doubt when using regex for password validation. BTW, your current code does not account for Unicode upper case letters. – Wiktor Stribiżew Jan 11 '16 at 08:00
  • Very good code – kazuwombat Jun 10 '20 at 03:18
9

I have created a simple method to validate all kind of password. You can edit your limit on that. Kindly find the code given below.

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 less than or greater than 12 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 characters";
        return false;
    }
    else
    {
        return true;
    }
}
Anurag
  • 557
  • 6
  • 14
8

there is problem with you regular expression

Regex regex = new Regex(@"^(.{0,7}|[^0-9]*|[^A-Z])$");

you applied character | which means either or.

form wiki

| -The choice (also known as alternation or set union) operator matches either the expression before or the expression after the operator. For example, abc|def matches "abc" or "def".

which means that in your regular expression it either matches .{0,7} part or [^0-9]*|[^A-Z] - that is why its returning true to you in any case.


You can use this regex:

^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$

This regex will enforce these rules: • At least one upper case english letter • At least one lower case english letter • At least one digit • At least one special character • Minimum 8 in length

refered from : Regex for Password Must be contain at least 8 characters, least 1 number and both lower and uppercase letters and special characters

Community
  • 1
  • 1
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
  • Thanks Pranay, Thanks for helping me out. I've understood the wrongdoings in the question. Previously I was trying to sort it out with `|` whether it should concatenate the string and then validate. Your explanation is great too! – Manoz Jan 11 '16 at 06:58
  • 2
    I'd STRONGLY urge anyone using this code to refactor this regex into several simpler regexes, each corresponding to one, or at least fewer business rules. A "big" (yes, I know there are bigger) regex like this is a nightmare to understand, maintain and tweak. If you also don't have any covering automatic tests it's just gonna end up being one of those LoC that is "forbidden" for everyone to touch, because "it might break". – sara Jan 11 '16 at 07:03
  • @kai - agree with you sometime its better to break down..simple and easy way to understanding...:) – Pranay Rana Jan 11 '16 at 07:04
  • 3
    Thanks for the regex. Just to add, I do agree that breaking this down will help with readability but if you are using data annotations in your class then you need to use regex. – tdean Mar 16 '16 at 01:33
0

Pattern satisfy, these below criteria

  1. Password of Length 8
  2. Requires at least 1 Unique Char.
  3. Requires 1 Digit
  4. Requires 1 Lower Case character
  5. Requires 1 Upper Case character
  6. Requires 1 Special Character

^(?!.([A-Za-z0-9])\1{1})(?=.?[A-Z])(?=.?[a-z])(?=.?[0-9])(?=.?[#?!@$%^&-]).{8,}$

For example:- It satisfies password like:- Admin@123

MayankGaur
  • 957
  • 11
  • 22
-1

Ok, Found out to be a change in expression. A good explanation by @mmdemirbas here-

Password must be 8 characters including 1 uppercase letter, 1 special character, alphanumeric characters

(                   # Start of group
    (?=.*\d)        #   must contain at least one digit
    (?=.*[A-Z])     #   must contain at least one uppercase character
    (?=.*\W)        #   must contain at least one special symbol
       .            #     match anything with previous condition checking
         {8,8}      #        length at least 8 characters and also maximum of 8
)                   # End of group

My end expression now is-

((?=.*\d)(?=.*[A-Z]).{8,50})

Thanks everyone for stopping by.

working here- https://dotnetfiddle.net/lEFYGJ

Community
  • 1
  • 1
Manoz
  • 6,507
  • 13
  • 68
  • 114
  • You can use `{8,}` instead of `{8,50}` if you don't want to limit the password length. – fero Jan 11 '16 at 06:54
  • @fero, Thanks, Just realized. – Manoz Jan 11 '16 at 06:54
  • Check my answer ..its give you what is error with prevous string and some good reg from already answered SO question – Pranay Rana Jan 11 '16 at 06:55
  • 1
    @Manoz: Use `^(?=\D*\d)(?=\P{Lu}*\p{Lu}).{8}$` if you plan to only force the password to have at least 1 digit, 1 any Unicode uppercase letter and be exactly 8 chars long (allowing any characters but a newline). If you want to enforce at least one non-word character ("special" character), add `(?=\w*\W)`. **Note the `^` and `$` anchors in my regex, they are crucial to allow checking for length.** Use the principle of contrast. See [*Lookahead Example: Simple Password Validation*](http://www.rexegg.com/regex-lookarounds.html#password). – Wiktor Stribiżew Jan 11 '16 at 08:05
  • @stribizhev, Thanks. The link is great resource. – Manoz Jan 11 '16 at 12:18
-3

You can use this,

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