Regex для проверки> 1 верхнего, нижнего, цифрового и специального символа - PullRequest
1 голос
/ 01 марта 2010

^. (? =. {15}) (? =. \ г) (? =. [AZ]) (? =. [AZ]) ( ? =. [! @ # $% ^ & + =]). * $

Это регулярное выражение, которым я сейчас пользуюсь, которое оценивает по 1 каждому: верхняя, нижняя, цифра и спецпредложения по моему выбору. Вопрос, который у меня есть, как сделать так, чтобы он проверял 2 из каждого из них? Также я спрашиваю, потому что, казалось бы, трудно написать тестовый пример для этого, поскольку я не знаю, оценивает ли он только первый набор критериев, в которых он нуждается. Это пароль, однако требуется, чтобы он был в форме регулярного выражения в зависимости от используемого нами пакета.

EDIT

Ну, так как я спешу проверить выражение, которое я забыл, чтобы проверить длину моей строки. Спасибо Кену и Гамбо за помощь в этом.

Это код, который я выполняю:

Я прошу прощения, так как регулярное выражение не моя область.

Пароль, который я использую, является следующей строкой "$$ QiouWER1245", поведение, которое я испытываю в данный момент, заключается в том, что он случайным образом выбирает, пройти или не пройти. Есть мысли по этому поводу?

Pattern pattern = Pattern.compile(regEx);
Matcher match = pattern.matcher(password);  
while(match.find()){
    System.out.println(match.group()); 
}

Из того, что я вижу, если он оценивается как true, он вернет мне значение в пароле, иначе это пустая строка.

Ответы [ 4 ]

3 голосов
/ 01 марта 2010

Лично я считаю, что политика паролей, которая заставляет использовать все три класса символов, не очень полезна. Вы можете получить такую ​​же степень случайности, позволяя людям создавать более длинные пароли. Пользователи будут склонны разочаровываться и записывать пароли, если им придется соблюдать слишком много правил для паролей (которые делают пароли слишком сложными для запоминания). Я рекомендую подсчитать биты энтропии и убедиться, что они больше 60 (обычно требуется пароль из 10-14 символов). Энтропия на символ будет примерно зависеть от количества символов, диапазона используемых им наборов символов и, возможно, от того, как часто они переключаются между наборами символов (я думаю, пароли типа HEY более предсказуемы, чем heYThEre).

Еще одно примечание: планируете ли вы не считать символы справа от клавиатуры (точка, запятая, угловые скобки и т. Д.)?

Если вам все еще нужно найти группы из двух символов, почему бы просто не повторить каждый шаблон? Например, сделайте (? =. \ d) в (? =. \ d. * \ D).

Для ваших тестовых случаев, если вы беспокоитесь о том, что он проверит только первые критерии, напишите тестовый пример, который гарантирует, что каждый из следующих паролей будет неудачным (поскольку один и только один из критериев не выполняется в каждом случае ): Просто для забавы я изменил порядок ожидания каждого набора символов, хотя это, вероятно, не будет иметь значения, если кто-то не удалит / забудет? = В какой-то момент в будущем.

!@#TESTwithoutnumbers
TESTwithoutsymbols123
&*(testwithoutuppercase456
+_^TESTWITHOUTLOWERCASE3498

Я должен отметить, что технически ни один из этих паролей не должен быть приемлемым, поскольку они используют словарные слова, которые имеют примерно 2 бита энтропии на символ вместо чего-то более похожего на 6. Однако я понимаю, что трудно написать (обслуживаемый и эффективно) регулярное выражение для проверки словарных слов.

2 голосов
/ 01 марта 2010

Если я правильно понимаю ваш вопрос, вам нужно не менее 15 символов и требовать не менее 2 символов верхнего регистра, не менее 2 символов нижнего регистра, как минимум 2 цифры и не менее 2 специальных символов В таком случае вы можете это так:

^.*(?=.{15,})(?=.*\d.*\d)(?=.*[a-z].*[a-z])(?=.*[A-Z].*[A-Z])(?=.*[!@#$%^&*+=].*[!@#$%^&*+=]).*$

Кстати, у вашего исходного регулярного выражения была дополнительная обратная косая черта до \ d

2 голосов
/ 01 марта 2010

Попробуйте это:

"^(?=(?:\\D*\\d){2})(?=(?:[^a-z]*[a-z]){2})(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^!@#$%^&*+=]*[!@#$%^&*+=]){2}).{15,}$"

Здесь группы без захвата (?:…) используются для группировки условий и их повторения. Я также использовал дополнения каждого класса символов для оптимизации вместо универсального ..

1 голос
/ 01 марта 2010

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

Я предлагаю структурировать код следующим образом:

  • проверьте, что строка содержит 2 строчных символа
    • возврат ошибки, если не найден, или продолжение
  • проверить, что строка содержит 2 заглавных символа
    • возврат ошибки, если не найден, или продолжение
  • и т.д.

Это также позволит вам передать код возврата или строку ошибок, указывающую, почему пароль не был принят, и код будет намного проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...