Java с использованием регулярных выражений - PullRequest
4 голосов
/ 12 августа 2010

Я работаю со сбросом паролей.Мне нужен способ в Java с использованием регулярных выражений для сброса пароля, чтобы он не мог содержать 4 последовательных символа от предыдущего пароля.

Ответы [ 5 ]

4 голосов
/ 12 августа 2010

Я не думаю, что регулярное выражение является подходящим инструментом для этой задачи.

На самом деле, я не вижу другого решения, кроме цикла, который попытается найти подстроку из 4 общих символов.

2 голосов
/ 12 августа 2010

Вы должны построить это динамически. Скажем, у вас есть предыдущий пароль «tiddlywinks». Это означало бы, что следующее не разрешено:

Tidd iddl DDLY dlyw lywi ywin чернила

Так получилось, что это хорошо и заканчивается на границе 4 символов. Не планировал этого. Тем не мение. Пройдите ваш предыдущий пароль примерно так:

public Pattern toValidationExpression( String previousPassword ) {
   StringBuilder builder = new StringBuilder();
   for( int i = 0; i < previousPassword.length()-4; i++ ) {
      if( i > 0 ) builder.append( "|" );
      builder.append( "(" );
      builder.append( previousPassword.substring(i, Math.min( i+4, previousPassword.length() );
      builder.append( ")" );
   }
   return Pattern.compile( builder.toString() );
}
2 голосов
/ 12 августа 2010

Регулярные выражения не являются решением всех мировых проблем. Код был бы намного проще и понятнее, если бы вы реализовали это как обычный цикл с проверкой indexOf.

редактировать
Я предполагаю, что вы планируете использовать его в каком-то приложении. Если вы спросите просто из любопытства, то я не знаю :)

1 голос
/ 12 августа 2010

С некоторыми разумными ограничениями это можно сделать довольно просто с помощью регулярных выражений.

Если предположить, что \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 дополнения !.

Это не самое эффективное решение проблемы, но при условии, что пароли имеют разумную длину, скорость не будет проблемой.

Ссылки

0 голосов
/ 12 августа 2010

Итак, давайте предположим, что вы используете char [] вместо String для хранения старых / новых паролей, чтобы быть в некоторой степени безопасными.У экспертов по безопасности есть лучшие инструменты ... шифрование / хеширование / и т.д. ... для управления паролями.

Итак, вот что:

/**
 * Compare old to new password to a repeating 4char sequence.
 * -> require passNew to be >= 4char sequence, else return false.
 * -> require passOld to be >= 4char sequence, else return true.
 * -> utilize shifting long to handle full 16Bit char range.
 * -> does not support char beyond 16Bit char range... e.g. codepoint > 2^16.
 * -> codepoint > 2^16 support could be done with XOR 4 codepoints with 8bit shifts
 * @return success true if passNew >= 4char sequence,
 *    passOld lessthan 4char sequence or
 *    normal... 4char sequence not found.
 */
public final boolean validatePassword(char[] passOld, char[] passNew) {
    if (passNew.length lessthan 4) {
        return (false);
    } else if (passOld lessthan 4) {
        return (true);
    }
    long patOld = ((passOld[0] & 0x0ffL) leftshift 32) |
        ((passOld[1] & 0x0ffL) leftshift 16) |
        (passOld[2] & 0x0ffL);
    long patNewOrig = ((passNew[0] & 0x0ffL) leftshift 32) |
        ((passNew[1] & 0x0ffL) leftshift 16) |
        (passNew[2] & 0x0ffL);
    long patNew;
    int offOld = 2, lenOld = passOld.length
    int offNew = 2, lenNew = passNew.length;
    while (++offOld lessthan lenOld) {
        patOld = (patOld leftshift 16) | (passOld[offOld] & 0x0ffL);
        patNew = patNewOrig;
        offNew = 2;
        while (++offNew lessthan lenNew) {
            patNew = (patNew leftshift 16) | (passNew[offNew] & 0x0ffL);
            if (patOld == patNew) {
                return (false);
            }
        }
    }
    return (true);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...