Регулярное выражение для проверки пароля

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

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

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

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

Ответ 1

Здесь, похоже, много путаницы. Ответы, которые я вижу до сих пор, неправильно применяют правило 1+ number/1 + lowercase/1 + uppercase, что означает, что такие пароли, как 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. Это также легче читать и поддерживать, поэтому сделайте это, если у вас есть опция. Однако, если это относится к правилам проверки в разметке, вы, вероятно, застряли в одном регулярном выражении.

Ответ 2

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

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 года, которому нужно изменить ограничение, будет легче понимать время?

Ответ 3

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

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(@"[[email protected]#$%^&*()_+=\[{\]};:<>|./?,-]");

        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;
        }
    }

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

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

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

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

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

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

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

Ответ 7

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

\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

Ответ 8

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

//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(), @"[!#$%&'()*+,-.:;<=>[email protected][\\\]{}^_`|~]")) 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);