Reputation: 521
My application has a feature to check password. I need to get this scenario:
password length 10 ~ 32 .
It has to be a combination of either:
Current code in application:
private boolean isSpecialMixedText(String password)
{
String number = "[0-9]";
String english = "[a-zA-Z]";
String special = "[!@#\\$%^&*()~`\\-=_+\\[\\]{}|:\\\";',\\./<>?£¥\\\\]";
Pattern numberPattern = Pattern.compile(number);
Matcher numberMatcher = numberPattern.matcher(password);
Pattern englishPattern = Pattern.compile(english);
Matcher englishMatcher = englishPattern.matcher(password);
Pattern specialPattern = Pattern.compile(special);
Matcher specialMatcher = specialPattern.matcher(password);
return numberMatcher.find() && englishMatcher.find() || specialMatcher.find();
}
Please help me get the combination working
Upvotes: 3
Views: 187
Reputation: 5395
In my opinion your logic is wrong because you look for combination (so only these characters allowed) of: characters and numbers OR characters and special characters OR numbers and special characters. However with pair of matches like: [0-9]
and [a-zA-Z]
you are actually looking for a String with some digits and some letter, but it could be also 123ABC#$%#$%$#%#$
(because it has letters and digits).
What you need is something to check, if given string is composed ONLY of of allowed combination of characters. I think you can use one regex here (not too elegant, but effective) like:
^(?:((?=.*[A-Za-z].*)(?=.*[0-9].*)[A-Za-z0-9]{10,32})|((?=.*[-!@#\\$%^&*()~`\=_+\[\]{}|:\";',.\/<>?£¥\\].*)(?=.*[0-9].*)[0-9-!@#\\$%^&*()~`\=_+\[\]{}|:\";',.\/<>?£¥\\]{10,32})|((?=.*[-!@#\\$%^&*()~`\=_+\[\]{}|:\";',.\/<>?£¥\\].*)(?=.*[A-Za-z].*)[-A-Za-z!@#\\$%^&*()~`\=_+\[\]{}|:\";',.\/<>?£¥\\]{10,32}))$
DEMO - it show valid and invalid matches.
This is quite long regex, but mainly because of you special character class. This regular expression is composed of three parts with similar structure:
positive lookagead for required characters + character class of allowed characters
On an example:
(?=.*[A-Za-z].*)(?=.*[0-9].*)[A-Za-z0-9]{10,32}
means that string need to have:
(?=.*[A-Za-z].*)
- at least one letter (positive lookahead for letter which could be surrounded by other characters),(?=.*[0-9].*)
- at least one number (positive lookahead for digit which could be surrounded by other characters)[A-Za-z0-9]{10,32}
- from 10 to 32 letters or digits,
in effect, the given password need to have 10 to 32 characters, but both letters and digits, proportion is not important.Whats more, the ^
at beginning and $
in the end ensure that the whole examined string has such composition.
Also I would agree with others, it is not best idea to restrict allowed character in password like that, but it is your decision.
Upvotes: 1
Reputation: 718826
Actually, the regexes look fine. The problem is in this statement:
return numberMatcher.find() && englishMatcher.find() ||
specialMatcher.find();
It actually needs to be something like this:
boolean n = numberMatcher.find();
boolean e = englishMatcher.find();
boolean s = specialMatcher.find();
return (n && e) || (n && s) || (e && s);
And I agree with @adelphus' comment. Your rules for deciding what passwords are acceptable are very English-language-centric.
Upvotes: 2