С некоторыми разумными ограничениями это можно сделать довольно просто с помощью регулярных выражений.
Если предположить, что \n
является недопустимой частью пароля (ОЧЕНЬ разумное ограничение), то следующий код выполнит проверку вполне читабельно (если вы знаете, как читать регулярные выражения):
static boolean legalChange(String before, String after) {
String joined = String.format("%s\n%s", before, after);
return !joined.matches(".*(.{4}).*\n.*\\1.*");
}
Вот тестовый комплект ( см. Также на ideone.com ):
String[][] tests = {
{ "abcdef", "ghijklm" }, // true
{ "abcdef", "xbcdeyz" }, // false
{ "abcdef", "fedbcda" }, // true
{ "xyz", "" }, // true
{ "0123456789", "abc123def456ghi" }, // true
{ "0123456789", "abc123456ghi" }, // false
};
for (String[] test : tests) {
System.out.println(legalChange(test[0], test[1]));
}
Обратите внимание, что это регулярное выражение проверяет только правило "нет общей подстроки длины 4". Также должны быть введены дополнительные правила регулярного выражения пароля.
Как это работает
По сути, мы объединяем две строки в одну, ограниченную \n
(что опять же является недопустимым символом, который в любом случае должен быть в именах пользователей).
Это регулярное выражение будет соответствовать НЕЗАКОННО изменению:
before | after i.e. before = .* (.{4}) .*
| after = .* \1 .*
.*(.{4}).*\n.*\1.*
\____/
1
То есть мы сопоставляем (.{4})
из before
в группу 1 и используем обратную ссылку \1
, чтобы посмотреть, может ли она быть найдена в after
. Мы поместили .*
вокруг этих двух, чтобы событие произошло где угодно. Движок регулярных выражений выполнит весь необходимый возврат на .*
, чтобы проверить, может ли этот шаблон соответствовать.
Поскольку этот шаблон соответствует изменению ILLEGAL , мы аннулируем результат matches
с помощью оператора boolean
дополнения !
.
Это не самое эффективное решение проблемы, но при условии, что пароли имеют разумную длину, скорость не будет проблемой.
Ссылки