Regexp Java для перевірки пароля


109

Я створюю регулярний параметр для перевірки пароля, який буде використовуватися в додатку Java в якості параметра конфігурації.

Регепс:

^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$

Політика щодо паролів:

  • Не менше 8 символів

  • Містить принаймні одну цифру

  • Містить щонайменше одну нижню альфа-схему та одну верхню альфа-схему

  • Містить щонайменше один знак у наборі спеціальних символів ( @#%$^тощо)

  • Не містить місця, вкладки тощо.

Мені не вистачає лише пункту 5. Я не в змозі перевірити повторне оновлення місця, вкладки, повернення каретки тощо.

Може хтось мені допоможе?


3
Правила пароля погані. Будь ласка, див. Довідка - Перевірка пароля для отримання додаткової інформації.
ctwheels

Відповіді:


317

Спробуйте це:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$

Пояснення:

^                 # start-of-string
(?=.*[0-9])       # a digit must occur at least once
(?=.*[a-z])       # a lower case letter must occur at least once
(?=.*[A-Z])       # an upper case letter must occur at least once
(?=.*[@#$%^&+=])  # a special character must occur at least once
(?=\S+$)          # no whitespace allowed in the entire string
.{8,}             # anything, at least eight places though
$                 # end-of-string

Додавати, змінювати або видаляти окремі правила легко, оскільки кожне правило - це незалежний "модуль".

(?=.*[xyz])Конструкція з'їдає весь рядок ( .*) і відкочується на перше входження , де [xyz]може відповідати. Він [xyz]виявляється успішним, якщо його знайдуть, не вдається інакше.

Альтернативою буде використовувати неохоче специфікатор: (?=.*?[xyz]). Для перевірки паролем це навряд чи матиме значення, для набагато довших рядків це може бути більш ефективним варіантом.

Звичайно, найефективніший варіант (але найскладніший для читання та підтримки, тому найбільш схильний до помилок) (?=[^xyz]*[xyz]). Для регексу такої довжини і для цієї мети я б рекомендував робити це саме так, оскільки це не має реальних переваг.


15
@ Kerby82: У рядках Java слід повернути косої риски. Спробуйте використовувати \\s. Це вимога Java, а не вимога регулярного вираження.
Томалак

1
@Allov Просто подумайте про це так: Все, що не виконується, не є обов'язковим. Просто зніміть чеки на речі, які ви не хочете застосовувати. Має бути легко адаптувати рішення до ваших потреб.
Томалак

3
Ця відповідь була додана до поширених запитань щодо регулярного вираження стека в розділі "Загальні завдання на перевірку".
aliteralmind

1
@ shA.t Це те саме. Я лише намагався зберегти (?=...)шаблон, щоб він відповідав налаштуванню решти виразу ..
Tomalak

2
@ shA.t Незалежно від того, чи скажете ви, що "містить лише пробіли" ( (?=\S+$)) або "не містить символів пробілу" ( (?!.*\s)). Використовуйте все, що вам більше подобається. :)
Томалак

55

простий приклад з використанням регулярного вираження

public class passwordvalidation {
    public static void main(String[] args) {
      String passwd = "aaZZa44@"; 
      String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
      System.out.println(passwd.matches(pattern));
   }
}

Пояснення:

  • (?=.*[0-9]) цифра повинна виникати хоча б один раз
  • (?=.*[a-z]) малі літери повинні виникати хоча б один раз
  • (?=.*[A-Z]) літери верхнього регістру повинні виникати хоча б один раз
  • (?=.*[@#$%^&+=]) спеціальний персонаж повинен виникнути хоча б один раз
  • (?=\\S+$) не допускається пробілів у всій рядку
  • .{8,} щонайменше 8 символів

5
. {5,10} представляє мінімум 5 символів і максимум 10 символів. Про всяк випадок, якщо хтось шукає конкретних пояснень.
абхи

@iabhi, я шукав це. Дякую.
Акшата Шрінівас

Я намагаюся реалізувати Regex на паролі, який зберігається в масиві char замість String через безпеку. Але як можна застосувати регулярний вираз до масиву char?
AgentM

13

Усі раніше задані відповіді використовують один і той же (правильний) прийом, щоб використовувати окрему підказку для кожної вимоги. Але вони містять пару неефективності та потенційно масову помилку, залежно від зворотного кінця, який фактично використовуватиме пароль.

Почну з регулярного вираження з прийнятої відповіді:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$

Перш за все, оскільки Java підтримує, \Aі \zя вважаю за краще використовувати їх, щоб переконатися, що вся нитка перевірена, незалежно від Pattern.MULTILINE. Це не впливає на продуктивність, але дозволяє уникнути помилок при переробці регулярних виразів.

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z

Перевірка того, що пароль не містить пробілу, і перевірка його мінімальної довжини може бути виконана за один прохід, використовуючи всі одразу, додавши змінний кількісний показник {8,}на скорочення, \Sщо обмежує дозволені символи:

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z

Якщо вказаний пароль містить пробіл, всі перевірки будуть зроблені, лише щоб остаточна перевірка не була пропущеною. Цього можна уникнути, замінивши всі крапки на \S:

\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z

Точку слід використовувати лише в тому випадку, якщо ви дійсно хочете дозволити будь-який символ. В іншому випадку використовуйте (заперечуваний) клас символів, щоб обмежити ваш регулярний вираз лише тими символами, які дійсно дозволені. Хоча в цьому випадку мало значення, не дуже корисно використовувати не крапку, коли щось інше є більш підходящим . Я бачу занадто багато випадків катастрофічного зворотного відстеження, оскільки розробник був лінивий, щоб використовувати щось більш відповідне, ніж крапка.

Оскільки є хороший шанс, що початкові тести знайдуть відповідний символ у першій половині пароля, лінивий кількісний показник може бути більш ефективним:

\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z

Але тепер для справді важливого питання: жодна з відповідей не згадує про те, що оригінальне запитання, здається, написав хтось, хто думає в ASCII. Але в Java рядки є Unicode. Чи допускаються символи, що не належать до ASCII, у паролях? Якщо вони є, заборонені лише пробіли ASCII або слід виключити весь пробіл Unicode.

За замовчуванням \sвідповідає лише пробіл ASCII, тому його обернена \Sвідповідність усім символам Unicode (пробіл чи ні) та всі символи ASCII, що не пробіли. Якщо символи Unicode дозволені, але пробіли Unicode - ні, UNICODE_CHARACTER_CLASSпрапор можна вказати, щоб \Sвиключити пробіл Unicode. Якщо символи Unicode заборонені, [\x21-\x7E]їх можна використовувати замість того, \Sщоб відповідати всім символам ASCII, які не є пробілом або символом управління.

Що приводить нас до наступного потенційного питання: чи хочемо ми дозволити контрольні символи? Перший крок у написанні правильного регулярного вираження - точно вказати, що ви хочете відповідати, а що - ні. Єдина стовідсотково технічно правильна відповідь - це те, що специфікація пароля у запитанні є неоднозначною, оскільки в ній не вказано, чи дозволені чи ні певні діапазони символів, такі як контрольні символи чи символи, що не належать до ASCII.


9

Не слід використовувати надмірно складні Regex (якщо ви можете їх уникнути), оскільки вони є

  • важко читати (принаймні для всіх, крім себе)
  • важко розширити
  • важко налагодити

Хоча при використанні багатьох малих регулярних виразів може бути невелика продуктивність, однак вище, ніж це, це легко переважає.

Я би реалізував так:

bool matchesPolicy(pwd) {
    if (pwd.length < 8) return false;
    if (not pwd =~ /[0-9]/) return false;
    if (not pwd =~ /[a-z]/) return false;
    if (not pwd =~ /[A-Z]/) return false;
    if (not pwd =~ /[%@$^]/) return false;
    if (pwd =~ /\s/) return false;
    return true;
}

І з точки зору безпеки набагато краще застосовувати довші паролі, запобігати відомим паролям (наприклад, 12345 і pass = користувач), а не робити паролі надскладними і важкими для запам'ятовування.
Мартін Раушер

Мені подобається ваш підхід вище. Дякую тобі за це!
Томас Ланг

1

Вимога до пароля:

  • Пароль повинен містити не менше восьми (8) символів, якщо система може його підтримувати.
  • Паролі повинні містити символи щонайменше з двох (2) цих груп: альфа, числові та спеціальні символи.

    ^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$

Я перевірив це, і він працює


1

Для всіх, хто цікавиться мінімальними вимогами до кожного типу символів, я б запропонував зробити наступне розширення над прийнятою відповіддю Томалака:

^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$

Зауважте, що це рядок форматування, а не остаточний шаблон регулярного виразів. Просто замініть% d мінімальними необхідними появами на: цифри, малі літери, великі регістри, нецифрові знаки / символи та весь пароль (відповідно). Максимальне число випадків малоймовірне (якщо ви не хочете максимум 0, фактично відхиляючи будь-які подібні символи), але їх також можна легко додати. Зауважте додаткове групування навколо кожного типу, щоб мінімальні / максимальні обмеження дозволяли проводити непослідовні збіги. Це творило чудеса для системи, в якій ми могли б центрально налаштувати кількість потрібних нам типів символів, а потім мати веб-сайт, а також дві різні мобільні платформи отримувати цю інформацію для побудови шаблону регулярного вираження на основі вищезазначеного рядка форматування.


1

Цей перевіряє на кожен спеціальний символ:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\S+$).*[A-Za-z0-9].{8,}$

1

Готовий для вас метод Java з параметрами

Просто скопіюйте та вставте та встановіть потрібні параметри.

Якщо ви не хочете модуля, просто прокоментуйте його або додайте "якщо", як це зроблено мною для особливих знаків

//______________________________________________________________________________
/**
 * Validation Password     */
//______________________________________________________________________________
private static boolean validation_Password(final String PASSWORD_Arg)    {
    boolean result = false;
    try {
        if (PASSWORD_Arg!=null) {
            //_________________________
            //Parameteres
            final String MIN_LENGHT="8";
            final String MAX_LENGHT="20";
            final boolean SPECIAL_CHAR_NEEDED=true;

            //_________________________
            //Modules
            final String ONE_DIGIT = "(?=.*[0-9])";  //(?=.*[0-9]) a digit must occur at least once
            final String LOWER_CASE = "(?=.*[a-z])";  //(?=.*[a-z]) a lower case letter must occur at least once
            final String UPPER_CASE = "(?=.*[A-Z])";  //(?=.*[A-Z]) an upper case letter must occur at least once
            final String NO_SPACE = "(?=\\S+$)";  //(?=\\S+$) no whitespace allowed in the entire string
            //final String MIN_CHAR = ".{" + MIN_LENGHT + ",}";  //.{8,} at least 8 characters
            final String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}";  //.{5,10} represents minimum of 5 characters and maximum of 10 characters

            final String SPECIAL_CHAR;
            if (SPECIAL_CHAR_NEEDED==true) SPECIAL_CHAR= "(?=.*[@#$%^&+=])"; //(?=.*[@#$%^&+=]) a special character must occur at least once
            else SPECIAL_CHAR="";
            //_________________________
            //Pattern
            //String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
            final String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
            //_________________________
            result = PASSWORD_Arg.matches(PATTERN);
            //_________________________
        }    

    } catch (Exception ex) {
        result=false;
    }

    return result;
}        



0

легкий

("^ (? =. * [0-9]) (? =. * [Az]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8 , 10} $ ")

  1. (? = що завгодно) -> означає, що позитивний з нетерпінням очікує у вхідному рядку і переконайтеся, що ця умова записана. якщо не написано, повернення неправдиве .

  2. (?! що-небудь) -> (навпаки) означає негативне очікування вперед, якщо умова написана return false .

    близьке значення ^ (умова) (умова) (умова) (умова) [\ S] {8,10} $


Хоча лише відповіді коду можуть вирішити проблему, деяке пояснення значно покращить якість відповіді.
Найджел Рен

0
String s=pwd;
int n=0;
for(int i=0;i<s.length();i++)
{
    if((Character.isDigit(s.charAt(i))))
    {
        n=5;
        break;
    }
    else
    {

    }
}
for(int i=0;i<s.length();i++)
{
    if((Character.isLetter(s.charAt(i))))
    {
        n+=5;
        break;
    }
    else
    {

    }

}

if(n==10)
{
    out.print("Password format correct <b>Accepted</b><br>");

}
else
{
    out.print("Password must be alphanumeric <b>Declined</b><br>");
}

Пояснення:

  1. Спочатку встановіть пароль як рядок та створіть цілий набір o.
  2. Потім перевірте кожну та кожну діаграму на наявність циклу.
  3. Якщо він знайде число в рядку, тоді n додайте 5. Потім перейдіть до наступного циклу. Character.isDigit (s.charAt (i))
  4. Цей цикл перевіряє алфавіти, розміщені в рядку. Якщо його знайти, то додайте ще одне 5 в n. Character.isLetter (s.charAt (i))
  5. Тепер перевірте ціле число n за умови умови if. Якщо n = 10 вірно, заданий рядок є буквено-цифровим, це не так.

0

Також ви можете зробити це, як це.

 public boolean isPasswordValid(String password) {


    String regExpn =
            "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$";

    CharSequence inputStr = password;

    Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(inputStr);

    if(matcher.matches())
        return true;
    else
        return false;
}

0

Приклад блоку коду для надійного пароля:

(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?=\\S+$).{6,18}
  1. щонайменше 6 цифр
  2. до 18 цифр
  3. одне число
  4. одна нижня літера
  5. одна велика літера
  6. може містити всі спеціальні символи

0

RegEx -

^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*)[^\s]{8,}$
  1. принаймні 8 цифр {8,}
  2. принаймні одне число (? =. * \ d)
  3. принаймні одна нижня літера (? =. * [az])
  4. принаймні одна велика літера (? =. * [AZ])
  5. принаймні один спеціальний символ (? =. * [@ # $% ^ & + =])
  6. Немає місця [^ \ s]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.