Ich möchte einen anderen Ansatz vorschlagen: keine Regex verwenden, aber jedes Zeichen überprüfen und Passwort Eigenschaften zu sammeln. Auf diese Weise können Sie später komplexere Anforderungen implementieren, z. "Es muss 3 von 4 haben".
Beispiel:
String pw = "1a!cde";
Set<PwProperty> passwordProperties = new HashSet<>();
for(char c : pw.toCharArray()) {
if(isDigit(c)) {
passwordProperties.add(PwProperty.DIGIT);
}
else if (isSpecialChar(c)) {
passwordProperties.add(PwProperty.SPECIAL);
}
else if(isUpperCase(c)) {
passwordProperties.add(PwProperty.UPPER_CASE);
}
else if(isLowerCase(c)) {
passwordProperties.add(PwProperty.LOWER_CASE);
}
else {
passwordProperties.add(PwProperty.UNKNOWN);
}
}
Dann könnten Sie, dass wie diese (Pseudocode):
if(!pw.length() in range) {
display "password too short" or "password too long"
}
if(passwordProperties.contains(PwProperty.UNKNOWN) {
display "unsupported characters used"
}
Set<PwProperty> setOf4 = { DIGIT, SPECIAL, LOWER_CASE, UPPER_CASE }
if(intersection(passwordProperties, setOf4).size() < 3) {
display "use at least 3 out of 4"
}
if(!passwordProperties.contains(DIGIT)) {
display "must contain digits"
}
display "password strength" being intersection(passwordProperties, setOfGoodProperties).size()
etc.
Dies kann dann beispielsweise erweitert werden mit Eigenschaften wie DIGIT_SEQUENCE
, die unerwünscht sein könnten usw.
Der Hauptvorteil besteht darin, dass Sie detailliertere Informationen zum Kennwort haben, als "es entspricht einer bestimmten Regex oder nicht", und Sie können diese Informationen verwenden, um den Benutzer zu führen.
Wenn Sie dies nur in Java tun, warum nicht einfach ein if/else verwenden, um dies in 2 Regexes basierend auf einer Anzahl von Zeichen zu brechen? Es ist technisch möglich und ich versuche, es jetzt hochzupeitschen ... –
Sie könnten einen Look-behing wie '(?! [0-9] {5} $)' –
@SebastianProske hinzufügen, der Sequenzen von 5 nicht erlauben würde Ziffern am Ende, aber was ist, wenn das Passwort etwas wie 'a12345' ist? – Thomas