1

I use java and a regexp.

I've made a regexp for password validation :

String PASSWORD_PATTERN_ADVANCED = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\\\\@#$¤£µ§%&<>,.!:?;~{-|`'_^¨éèçàù)=}()°\"\\]\\[²³*/+]).{8,20}$";

or without the extra slash :

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\\@#$¤£µ§%&<>,.!:?;~{-|`'_^¨éèçàù)=}()°"\]\[²³*/+]).{8,20}$

whuch means (i may be wrong): at least one digit / at least one lowercase / at least one uppercase / at least one of the special chars listed / with a minimum total length of 8 and a max of 20...

made a test case generating password for success and failure...

success -> OK, all passed failure -> Almost OK ...

The only password that fails to fail :D are the ones with space in it like :

 iF\ !h6 2A3|Gm 
¨I O7 gZ2%L£k vd~39 
2< A Uw a7kEw6,6S^ 
cC2c5N#  
6L kIw~ Béj7]5 
ynRZ #44ç 
9A `sè53Laj A 
s²R[µ3  9UrR q8n 

I am puzzled.

Any thoughts to make it works ?

Thanks

Antoine O
  • 171
  • 13
  • just in case..have you checked http://stackoverflow.com/q/3200292/1007273 ? – hovanessyan Jul 06 '12 at 14:40
  • @hovanessyan nice ! here is the direct link [link](http://code.google.com/p/vt-middleware/wiki/vtpassword) . I will definitely use it in my future dev. – Antoine O Jul 09 '12 at 14:13

3 Answers3

1

I may be wrong but if you simply don't want spaces then use [^\\s] instead of . in your lookahead.

String PASSWORD_PATTERN_ADVANCED = 
         "^(?=[^\\s]*\\d)"
        + "(?=[^\\s]*[a-z])"
        + "(?=[^\\s]*[A-Z])"
        + "(?=[^\\s]*[\\\\@#$¤£µ§%&<>,.!:?;~{-|`'_^¨éèçàù)=}()°\"\\]\\[²³*/+])"
        + ".{8,20}$";
Pshemo
  • 122,468
  • 25
  • 185
  • 269
1

A regex may not be the right tool for the job here.

Regexes are best suited for matching patterns; what you're describing isn't really a pattern, per se; it's more of a rule set. Sure, you may be able to create some regex that helps, but it's a really complex and opaque piece of code which make maintenance a challenge.

A method like this might be a better fit:

public boolean isValidPassword(String password) {
    boolean containsLowerCase;
    boolean containsUpperCase;
    boolean containsInvalid;
    boolean containsSpecialChar;
    boolean containsDigit;

    for(char c: password.toCharArray()) {
        containsLowerCase   ||= Character.isLowerCase(c);
        containsUpperCase   ||= Character.isUpperCase(c);
        containsDigit       ||= Character.isDigit(c); 
        containsSpecialChar ||= someMethodForDetectingIfItIsSpecial(c);

    }

    return  containsLowerCase &&
            containsUpperCase &&
            containsSpecialChar &&
            containsDigit &&
            !containsInvalid &&
            password.length >=8 && password.length <=20;

}

You'd need to decide the best way to detect a special character (specialCharArray.contains(c), regular expression, etc).

However, this approach would make adding new rules a lot simpler.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130
0

None of your conditions are stating what can't be in the password, only what must. You need one more condition that combines all the possible valid characters and makes sure all characters in the password are in that list (i.e., (\d|[a-z]|[A-Z]|@#$...){8,20} as the final condition). Either that or a list of rejected characters.

mellamokb
  • 56,094
  • 12
  • 110
  • 136