I have a list of passwords that I need to examine and determine if they meet the default 3 of 4 rule for AD.
Rule is contain 3 of the 4 following requirements: lower case character (a-z) upper case character (A-Z) numeric (0-9) special character ( !@#$%^&*()_+= )
I am still learning Regex. I know how to select only those that meet any one character case, but I am not sure how to do 3 of 4.
As a side note, the AD Complexity has two more subtleties that are important (but out of scope of the original question).
It is really 3 of 5. The fifth is Unicode character. Be nice to update the Regex with that.
The other is you cannot have the sAMAccountName value in whole in the password (case insensitive), nor if you split the displayName value into tokens split upon space, comma, dash, underscore, pound, pipe and something else those tokens (3 chars and longer) cannot be in whole in the password, case insensitive.
If you really want one big regex it would be something like this:
(?=^.{8,255}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*
Note that it also enforces password length to be between 8 and 255 characters. You can change the "{8,255}" portion in the first section to adjust the length requirements. It is also worth noting that this is working for me in a standard ASP.NET RegularExpressionValidator control.
Matches: "Passw0rd" "passW@rd" "1B2a345@#$%"
Non-Matches: "123123123" "Password" "asdf&"
Source (Matthew Hazzard via RegExLib.com)
Does it have to be all one big regex? You could do 4 regexes, each checking one thing and then make sure 3 of the 4 are matches. That would be easier, less error prone and more maintainable.
You will have to build up the regular expression like this:
rule = [ "[a-z]", "[A-Z]", "[0-9]", "[!@#$%\^\&\(\)\+=]" ]
regex = ""
first = true
for a in 0..3:
for b in 0..3:
if a == b: continue
for c in 0..3:
if a == c or b == c: continue
if not first:
regex += "|"
regex += "(" + rule[a] + ".*" + rule[b] + ".*" + rule[c] + ")"
first = false
I'm not sure if I escaped the special characters correctly. It's kind of dependant on the language/toolkit you're using.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With