Регулярное выражение для проверки пароля - PullRequest
45 голосов
/ 02 мая 2011

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

Условия строка должна быть длиной от 8 до 15 символов. Строка должна содержать хотя бы одно число. Строка должна содержать хотя бы одну заглавную букву. Строка должна содержать хотя бы одну строчную букву.

(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,15})$

По большей части работает, но не позволяет использовать специальные символы. Любая помощь, изменяющая это регулярное выражение, чтобы позволить специальный символ очень ценится.

Ответы [ 9 ]

79 голосов
/ 02 мая 2011

Кажется, здесь много путаницы. Ответы, которые я вижу до сих пор, неправильно применяют правило 1+ число / 1 + строчные / 1 + прописные, то есть такие пароли, как abc123 , 123XYZ или AB * & ^ # все равно будет принято. Недопустимо предотвращать использование строчных букв, заглавных букв или цифр; Вы должны обеспечить присутствие хотя бы одного из них.

Попробуйте следующее:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,15}$

Если вам также требуется хотя бы один специальный символ (что, вероятно, является хорошей идеей), попробуйте следующее:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$

.{8,15} можно сделать более строгим, если вы хотите (например, вы можете изменить его на \S{8,15}, чтобы запретить пробелы), но помните, что это снизит надежность вашей схемы паролей.

Я протестировал этот шаблон и он работает, как и ожидалось. Проверено на ReFiddle здесь: http://refiddle.com/110


Редактировать: Одна небольшая заметка, самый простой способ сделать это - 3 отдельных регулярных выражения и свойство Length строки. Это также легче читать и поддерживать, так что делайте это так, если у вас есть возможность. Если это для правил проверки в разметке, вы, вероятно, застряли с одним регулярным выражением.

42 голосов
/ 02 мая 2011

Является ли регулярное выражение более простым / лучшим способом применения простого ограничения, чем более очевидный способ?

static bool ValidatePassword( string password )
{
  const int MIN_LENGTH =  8 ;
  const int MAX_LENGTH = 15 ;

  if ( password == null ) throw new ArgumentNullException() ;

  bool meetsLengthRequirements = password.Length >= MIN_LENGTH && password.Length <= MAX_LENGTH ;
  bool hasUpperCaseLetter      = false ;
  bool hasLowerCaseLetter      = false ;
  bool hasDecimalDigit         = false ;

  if ( meetsLengthRequirements )
  {
    foreach (char c in password )
    {
      if      ( char.IsUpper(c) ) hasUpperCaseLetter = true ;
      else if ( char.IsLower(c) ) hasLowerCaseLetter = true ;
      else if ( char.IsDigit(c) ) hasDecimalDigit    = true ;
    }
  }

  bool isValid = meetsLengthRequirements
              && hasUpperCaseLetter
              && hasLowerCaseLetter
              && hasDecimalDigit
              ;
  return isValid ;

}

Что, по вашему мнению, программисту по обслуживанию через 3 года, которому необходимо изменить ограничение, будетВам легче понять?

9 голосов
/ 01 декабря 2016

Вы можете попробовать этот метод:

private bool ValidatePassword(string password, out string ErrorMessage)
    {
        var input = password;
        ErrorMessage = string.Empty;

        if (string.IsNullOrWhiteSpace(input))
        {
            throw new Exception("Password should not be empty");
        }

        var hasNumber = new Regex(@"[0-9]+");
        var hasUpperChar = new Regex(@"[A-Z]+");
        var hasMiniMaxChars = new Regex(@".{8,15}");
        var hasLowerChar = new Regex(@"[a-z]+");
        var hasSymbols = new Regex(@"[!@#$%^&*()_+=\[{\]};:<>|./?,-]");

        if (!hasLowerChar.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one lower case letter";
            return false;
        }
        else if (!hasUpperChar.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one upper case letter";
            return false;
        }
        else if (!hasMiniMaxChars.IsMatch(input))
        {
            ErrorMessage = "Password should not be less than or greater than 12 characters";
            return false;
        }
        else if (!hasNumber.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one numeric value";
            return false;
        }

        else if (!hasSymbols.IsMatch(input))
        {
            ErrorMessage = "Password should contain At least one special case characters";
            return false;
        }
        else
        {
            return true;
        }
    }
3 голосов
/ 02 мая 2011

Я думаю, это должно быть так:

(?!^[0-9]*$)(?!^[a-zA-Z]*$)^(.{8,15})$

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

2 голосов
/ 02 мая 2011

Попробуйте это (также исправлена ​​проверка для верхнего и нижнего регистров, в ней была ошибка, так как вы сгруппировали их как [a-zA-Z], она ищет только по крайней мере одну нижнюю или верхнюю. Таким образом, они отделены):

(?!^[0-9]*$)(?!^[a-z]*$)(?!^[A-Z]*$)^(.{8,15})$

Обновление: я обнаружил, что регулярное выражение на самом деле не работает должным образом, и это не так, как это должно быть написано тоже!

Попробуйте что-то вроде этого:

(?=^.{8,15}$)(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?!.*\s).*$

(от 8 до 15 включительно, содержит по крайней мере одну цифру, по крайней мере одну прописную и по крайней мере одну строчную букву и без пробелов.)

И я думаю, что это легче понятьа также.

2 голосов
/ 02 мая 2011

Я бы проверял их один за другим;то есть ищите число \d+, тогда, если это не удастся, вы можете сказать пользователю, что ему нужно добавить цифруЭто позволяет избежать возврата «недопустимой» ошибки, не сообщая пользователю, что с ней не так.

0 голосов
/ 03 февраля 2018

Может быть попробовать это:

(^[\S]*(?=.*[a-z])(?=.*[A-Z])(?=.*[\d])(?=.*[\W_])[\S]{8,15}$)

Кроме того, вы можете использовать эту страницу для проверки регулярных выражений:

http://rubular.com/r/ckRwasekcd

0 голосов
/ 08 июня 2012

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

//You can set these from your custom service methods
int minLen = 8;
int minDigit 2;
int minSpChar 2;

Boolean ErrorFlag = false;
//Check for password length
if (model.NewPassword.Length < minLen)
{
    ErrorFlag = true;
    ModelState.AddModelError("NewPassword", "Password must be at least " + minLen + " characters long.");
}

//Check for Digits and Special Characters
int digitCount = 0;
int splCharCount = 0;
foreach (char c in model.NewPassword)
{
    if (char.IsDigit(c)) digitCount++;
    if (Regex.IsMatch(c.ToString(), @"[!#$%&'()*+,-.:;<=>?@[\\\]{}^_`|~]")) splCharCount++;
}

if (digitCount < minDigit)
{
    ErrorFlag = true;
    ModelState.AddModelError("NewPassword", "Password must have at least " + minDigit + " digit(s).");
}
if (splCharCount < minSpChar)
{
    ErrorFlag = true;
    ModelState.AddModelError("NewPassword", "Password must have at least " + minSpChar + " special character(s).");
}

if (ErrorFlag)
    return View(model);
0 голосов
/ 02 мая 2011

Долго и может быть сокращено. Поддерживает специальные символы ?"-_.

\A(?=[-\?\"_a-zA-Z0-9]*?[A-Z])(?=[-\?\"_a-zA-Z0-9]*?[a-z])(?=[-\?\"_a-zA-Z0-9]*?[0-9])[-\?\"_a-zA-Z0-9]{8,15}\z
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...