tags:

views:

109

answers:

3

I need strong password validation regex

Special Characters - Not Allowed
Spaces - Not Allowed
Numeric Character - At least one character
At least one Capital Letter 
Minimum and Maximum Length of field - 6 to 12 Characters
Repetitive Characters - Allowed only two repetitive characters

my Regex is ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)(?=(?:(\w)(?!\1{2}))+).{6,12}$ but it ignores special characters (where to add?)

Please help!

+8  A: 

Doesn't sound like a task particularly suited for Regex, since you want to test multiple conditions simultaneously. (You could use multiple regexes, but then normal C# with LINQ is a nicer way to test it.) Try the following function:

public static bool IsStrongPassword(string password)
{
    // Minimum and Maximum Length of field - 6 to 12 Characters
    if (password.Length < 6 || password.Length > 12)
        return false;

    // Special Characters - Not Allowed
    // Spaces - Not Allowed
    if (!(password.All(c => char.IsLetter(c) || char.IsNumeric(c))))  
        return false;

    // Numeric Character - At least one character
    if (!password.Any(c => char.IsNumeric(c)))
        return false;

    // At least one Capital Letter
    if (!password.Any(c => char.IsUpper(c)))
        return false;

    // Repetitive Characters - Allowed only two repetitive characters
    var repeatCount = 0;
    var lastChar = '\0';
    foreach(var c in password)
    {
        if (c == lastChar)
            repeatCount++;
        else
            repeatCount = 0;
        if (repeatCount == 2)
            return false;
        lastChar = c;
    }

    return true;
}

Make sure you import System.Linq of course, and you're set to go.

Noldorin
Repetative characters ?
Maxim
Maybe one could combine the above LINQ approach with a couple of regexps that test stuff that regexps are good at?
Martin Wickman
@Maxim: Edited, that's included now. Repetitive characters is the only test I *might* do using regex, but I think the current approach is still fine.
Noldorin
+1: This method looks more maintainable than using a single regex. IMO even breaking down the single regex into smaller ones would be a step in the right direction.
Phil
+1  A: 

You can search the regex library

simendsjo
+4  A: 
^(?=.*[A-Z])(?=.*\d)(?!.*(.)\1\1)[a-zA-Z0-9@]{6,12}$
  • Special Characters - Not Allowed
  • Spaces - Not Allowed
  • Minimum and Maximum Length of field - 6 to 12 Characters
    Met by [a-zA-Z0-9@]{6,12}
  • Numeric Character - At least one character
    Met by positive lookahead (?=.*\d)
  • At least one Capital Letter
    Met by positive lookahead (?=.*[A-Z])
  • Repetitive Characters - Allowed only two repetitive characters
    I am not sure what you mean by this. The negative lookahead (?!.*(.)\1\1) makes sure that no character is allowed to appear more than two times in a row. Substring aa is okay, aaa is not.
    Make it (?!.*(.+)\1\1) to reject repeated substrings of length more than one (like ababab) or add .* before \1 to reject non-continuous repeated appearances too.
Amarghosh
Repetitive Characters - i mean: allowed paassword, and not allowed paaassword or passsword. What i need to do in this case?
Maxim
I still insist my code is much more readable/maintainable! Bah, regex for everyting and anything.
Noldorin
@Maxim It seems my understanding was correct. The given regex should do it.
Amarghosh
@Noldorin I kind of agree with you. Regexes and kids are alike - understanding/maintaining someone else's stuff can be a headache. That said, regex is compact and its fun to write them :)
Amarghosh
@Amarghosh: Fun to write indeed, just not to read heh. Thus the downfall of Perl...
Noldorin
@Noldorin OP asked for regex, and he got one. If you ask me if I'd use (or be allowed to use) this regex in the production code with many people working on it...
Amarghosh
No no, I don't blame you. Just taking the opportunity to have a good rant. :)
Noldorin
@Noldorin too bad it ended so fast :)
Amarghosh