views:

14562

answers:

4

I have a validation control that has the following expression:

(?=(.*\\d.*){2,})(?=(.*\\w.*){2,})(?=(.*\\W.*){1,}).{8,}

That's a password with atleast 2 digits, 2 alpha characters, 1 non-alphanumeric and 8 character minimum. Unfortunately this doesn't seem to be cross-browser compliant.

This validation works perfectly in Firefox but does not in IE.

A combination of each of your answers results in:

var format = "^(?=.{" + minLength + ",})" + 
    (minAlpha > 0 ? "(?=(.*[A-Za-z].*){" + minAlpha + ",})" : "") + 
    (minNum > 0 ? "(?=(.*[0-9].*){" + minNum + ",})" : "") + 
    (minNonAlpha > 0 ? "(?=(.*\\W.*){" + minNonAlpha + ",})" : "") + ".*$";

EX: "^(?=.{x,})(?=(.*[A-Za-z].*){y,})(?=(.*[0-9].*){z,})(?=(.*\W.*){a,}).*$"

The important piece is having the (?.{x,}) for the length first.

**Thanks :D**

A: 

How about one of the existing jQuery based password strength validators - like: http://simplythebest.net/scripts/ajax/ajax_password_strength.html

David Laing
No good. Then he'd need to validate again server-side and maintain the logic twice.
Joel Coehoorn
You really should be validating on the server side regardless of what client side validation may have been done. There's no guarantee the client did anything you think it should (The browser may have javascript disabled, The client may not even be a browser.).
marcj
+9  A: 

(?=(.*\W.*){0,}) is not 0 non-alphanumeric characters. It is at least 0 non-alphanumeric characters. If you wanted the password to not contain any non-alphanumeric characters you could do either (?!.*\W) or (?=\w*$).

A simpler solution would be to skip the \W look-ahead, and use \w{8,} instead of .{8,}.

Also, \w includes \d. If you wanted just the alpha you could do either [^\W\d] or [A-Za-z].

/^(?=(?:.*?\d){2})(?=(?:.*?[A-Za-z]){2})\w{8,}$/

This would validate the password to contain at least two digits, two alphas, be at least 8 characters long, and contain only alpha-numeric characters (including underscore).

  • \w = [A-Za-z0-9_]
  • \d = [0-9]
  • \s = [ \t\n\r\f\v]

Edit: To use this in all browsers you probably need to do something like this:

var re = new RegExp("^(?=(?:.*?\\d){2})(?=(?:.*?[A-Za-z]){2})\\w{8,}$");
if (re.test(password)) { /* ok */ }

Edit2: The recent update in the question almost invalidates my whole answer. ^^;;

You can should still be able to use the javascript code in the end, if you replace the pattern with what you had originally.

Edit3: OK. Now I see what you mean.

/^(?=.*[a-z].*[a-z])(?=.*[0-9].*[0-9]).{3,}/.test("password123") // matches
/^(?=.*[a-z].*[a-z])(?=.*[0-9].*[0-9]).{4,}/.test("password123") // does not match
/^(?=.*[a-z].*[a-z]).{4,}/.test("password123")                   // matches

It seems (?= ) isn't really zero-width in IE.

http://development.thatoneplace.net/2008/05/bug-discovered-in-internet-explorer-7.html

Edit4: More reading: http://blog.stevenlevithan.com/archives/regex-lookahead-bug

I think this can solve your problem:

/^(?=.{8,}$)(?=(?:.*?\d){2})(?=(?:.*?[A-Za-z]){2})(?=(?:.*?\W){1})/
new RegExp("^(?=.{8,}$)(?=(?:.*?\\d){2})(?=(?:.*?[A-Za-z]){2})(?=(?:.*?\\W){1})")

The (?=.{8,}$) needs to come first.

MizardX
Yea I saw that right before you posted, tested and it worked :D
nyxtom
+1  A: 

This will get you 2 min digits, 2 min characters, and min 8 character length... I refuse to show you how to not allow users to have non-alphanumeric characters in their passwords, why do sites want to enforce less secure passwords?

^(?=.*\d{2})(?=.*[a-zA-Z]{2}).{8,}$
sontek
Haha I agree :P The 0 was there because it's set server-side (it's a minimum rather than a 'you can have 0 non-alphanumeric')
nyxtom
How does having non-alphanumeric chars make a password less secure?
Ben Doom
[Reread] ".. I refuse to show you how to **not** allow users to have non-alphanumeric characters"
nyxtom
A: 

which book refer for asp.net reg. expression validation language?

ravi