Click here to Skip to main content
15,886,857 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm tremendously stuck with implementing a regular expression for enforcing strong passwords. The RegEx I'm trying to implement must match a password with the following criteria:

  • Minimum length of 12 characters;
  • At least three uppercase letters;
  • At least three lowercase letters;
  • At least three digits;
  • At least three special characters.

Intensive searching led me towards RegEx samples that simply require the presence of one character of a specific type. Obviously that'd be enough for most users but in this case I'm delivering to a client who specifically demanded these criteria.

The best I could come up with was this:
^(?=.*[!@#$%^&*()\-_=+`~\[\]{}?|])(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{12,20}$

But unfortunately, this lets strings such as !A3aaaaaaaaaaaa pass trough with ease. I think I need to use {3,} somewhere in my expression but I can't wrap my head around it. Can anyone lend a hand?
Posted

What you are searching for is not a case for using Regular Expressions. RE's allow you to quantify how many characters of a set may occur in a row, but not how many in total. Writing a regular expression for what you are trying to do is not possible.
You're better of doing this with a validating function (make it pluggable if you need the flexibility). You can iterate over all the input characters and find out if the totals for all your classes of characters amount to the limits you've been set.

Regards,

Manfred
 
Share this answer
 
Comments
MirageCoder 4-Feb-13 7:31am    
Manfred, thank you for your response. I'm definitely not crafty in RegEx (I should chalk it on my 2013 new years resolution list) and it's possible I'm thinking of it differently as a tool. Iterating over the characters has definitely crossed my mind but it felt like reinventing the wheel. I'll reconsider that option.
Manfred Rudolf Bihy 4-Feb-13 8:13am    
I've just tried out Zoltán's regex with expression designer and think it'll work just fine for your requirement.
MirageCoder 4-Feb-13 8:36am    
Agreed. But thanks for lending a hand anyways!
Manfred R. Bihy's answer is mainly correct. But regexp is capable of counting total character counts using lookaheads (please look at this article: http://www.zorched.net/2009/05/08/password-strength-validation-with-regular-expressions/[^]).
But strong password validation usually goes beyond this: for example not allowing sequence repetitions (like 123x123), not allowing parts of the username to be used in the passwords, not allowing previous passwords to be used, and so one, which can not be handled with regexp.
As I see, your requirements can be checked using the methods presented in the linked article.

[Update]
The following formula could be the one you are looking for: ^.*(?=.{12,})(?=.*([a-z].*?){3,})(?=.*([A-Z].*?){3,})(?=.*([\d].*?){3,})(?=.*([\W].*?){3,}).*$
 
Share this answer
 
v2
Comments
MirageCoder 4-Feb-13 7:47am    
Hello Zoltán, thanks for your reply. Coincidentally I stumbled across the same article before I posted my question but I can't find the solution when it comes to validating minimum amounts of characters, just testing on whether they are present or not.

You're making valid points on stronger password validation such as the prevention of sequence repetitions, but those are irrelevant to the client as of now. Thank you for thinking ahead though!
Zoltán Zörgő 4-Feb-13 8:00am    
Look at the following formula: ^.*(?=.{12,})(?=.*([a-z].*?){3,})(?=.*([A-Z].*?){3,})(?=.*([\d].*?){3,})(?=.*([\W].*?){3,}).*$.
Manfred Rudolf Bihy 4-Feb-13 8:11am    
Very nice job! 5+
I've never thought of doing it this way before. :thumbsup:
Zoltán Zörgő 4-Feb-13 8:27am    
Thank you. Yeah, regex is a really great and powerful tool - and I am sure, I have lot to learn too...
MirageCoder 4-Feb-13 8:18am    
Hello Zoltan, I tried a similar expression earlier today but I couldn't get it to work. I tried your expression and tested it in multiple tools but unfortunately no luck. (But I'm doubting my implementation more than your solution) If the string Aa1!Bb2@Cc3# can be matched then it will be exactly what I need.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900