0

我正在为密码策略编写代码。

政策规定您不能使用已经使用过的相同字母。例如:密码 - 您不能使用密码,因为它有两个 's'

我怎样才能做到这一点?

编辑:

这是我的完整实现:

private static final String PASSWORD_DUPLICATE_CHARACTERS = "^(?:([a-zA-Z])(?!.*\\1))$";

pattern = Pattern.compile(PASSWORD_DUPLICATE_CHARACTERS);
this.checkForDuplicateLetters(LDAPNewUserPassword);

private boolean checkForDuplicateLetters(final String newPassword) throws LDAPException{
    LoggingEnt userEnt = new LoggingEnt();
    String userid = userEnt.getUseridCode();
    boolean foundDuplicate = false;

    matcher = pattern.matcher(newPassword);

    if (newPassword.matches(PASSWORD_DUPLICATE_LETTERS)){
        foundDuplicate = true;
        userEnt.setMsg1("Duplicate.");
        throw new LDAPException("Invalid password combination for " + userid, LDAPException.INVALID_CREDENTIALS);//BAristo
    } else {
        userEnt.setMsg1("Your password has been successfully changed.");
    }

    return matcher.matches();

}

4

3 回答 3

1

使用这个正则表达式:

private static final String PASSWORD_PATTERN_LOWER_8 = "^(?:([a-zA-Z])(?!.*\\1))$";
于 2013-07-12T07:17:38.527 回答
0

您可以使用否定的前瞻断言,如下所示:

<snip> PASSWORD_PATTERN_LOWER_8 = "(?i)^(?!.*(.).*\\1)";

解释:

(?i)  # Case-insensitive mode
^     # Match start of string (might be redundant, but won't hurt either)
(?!   # Assert that it's impossible to match...
 .*   # any string
 (.)  # that's followed by one character (captured into group 1)
 .*   # followed by any string
 \\1  # and a repetition of the character we captured before.
)     # End of lookahead

性能不会那么好,尤其是对于较长的字符串,因为在最坏的情况下,每个字符都必须与其他每个字符进行比较。

例如,密码.qwertzuiopasdfghjklöäyxcvbnm,.只有在正则表达式引擎超过 1000 步后才会被检测为无效,而qwertzuiopasdfghjklöäyxcvbnm,..会立即失败。

首先对字符串进行排序并直接查找后续字符可能是一个更好的主意:

<snip> PASSWORD_PATTERN_LOWER_8 = "(?i)^(?!.*(.)\\1)";
于 2013-07-12T07:16:42.287 回答
0

我会用这样的东西

^((.)(?!.*\1))+$

这将匹配字符串中没有重复字符的字符串

于 2013-07-12T07:41:00.093 回答