正则表达式用于密码验证

时间:2011-05-02 16:25:54

标签: c# .net regex

我目前使用此正则表达式来检查字符串是否符合一些条件。

条件是 string必须长度在8到15个字符之间。 string必须至少包含一个数字。 string必须至少包含一个大写字母。 string必须至少包含一个小写字母。

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

它在很大程度上起作用,但它不允许特殊字符。任何帮助修改此正则表达式以允许特殊字符的人都非常感激。

13 个答案:

答案 0 :(得分:79)

这里似乎有很多混乱。到目前为止我看到的答案没有正确执行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属性。它也更容易阅读和维护,所以如果你有选择那么这样做。但是,如果这是用于标记中的验证规则,那么您可能只使用单个正则表达式。

答案 1 :(得分:42)

正则表达式是一种比更明显的方式更容易/更好的方法来强制执行简单约束吗?

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年后需要修改约束的人会更容易理解吗?

答案 2 :(得分:9)

您可以尝试这种方法:

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 :(得分:3)

我认为应该是这样的:

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

这将检查您的角色类的约束,然后检查您是否有8到15个字符。哪些字符不再重要,因为您已经检查过您的约束是否匹配。

答案 4 :(得分:2)

我会一个一个地检查它们;即查找数字\d+,如果失败,您可以告诉用户他们需要添加数字。这可以避免返回“无效”错误,而不会暗示用户有什么错误。

答案 5 :(得分:2)

试试这个(同样更正检查大写和小写,它有一个错误,因为你将它们分组为[a-zA-Z]它只查找至少一个低或高。所以将它们分开):

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

更新:我发现正则表达式并没有按预期工作,这也不是它应该如何编写的!

尝试这样的事情:

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

(8到15之间,包含至少一个数字,至少一个大写,至少一个小写,没有空格。)

我认为这也更容易理解。

答案 6 :(得分:1)

满足以下条件

  1. 密码长度8
  2. 需要唯一字符
  3. 需要数字
  4. 要求小写
  5. 要求大写
^(?!.*([A-Za-z0-9])\1{1})(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$

答案 7 :(得分:1)

更新为以上贾斯汀的答案。如果要在MVC中使用“数据注释”来使用它,可以按照以下步骤操作

[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$", ErrorMessage = "Password must be between 6 and 20 characters and contain one uppercase letter, one lowercase letter, one digit and one special character.")]

答案 8 :(得分:0)

很长,也许可以缩短。支持特殊字符?"-_

\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

答案 9 :(得分:0)

谢谢尼古拉斯凯莉。我首先要使用正则表达式,但你写的内容改变了我的想法。保持这种方式要容易得多。

//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);

答案 10 :(得分:0)

^^(?=.*[A-Z]{"+minUpperCase+",})(?=.*[a-z]{"+minLowerCase+",})(?=.*[0-9]{"+minNumerics+",})(?=.*[!@#$\-_?.:{]{"+minSpecialChars+",})[a-zA-Z0-9!@#$\-_?.:{]{"+minLength+","+maxLength+"}$

答案 11 :(得分:0)

我已修改@Anurag 在其他问题中的回答以满足我的要求:

需要该方法返回一个列表,显示密码不符合我的策略的位置,因此首先创建了一个包含所有可能问题的 Enum

public enum PasswordPolicyIssue
{
        MustHaveNumber,
        MustHaveCapitalLetter,
        MustHaveSmallLetter,
        MustBeAtLeast8Characters,
        MustHaveSymbol
}

然后是验证方法,它返回 bool 并有一个输出列表:

public bool MeetsPasswordPolicy(string password, out List<PasswordPolicyIssue> issues)
{
        var input = password;
        issues = new List<PasswordPolicyIssue>();

        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 hasMinChars = new Regex(@".{8,}");
        var hasLowerChar = new Regex(@"[a-z]+");
        var hasSymbols = new Regex(@"[!@#$%^&*()_+=\[{\]};:<>|./?,-]");

        if (!hasLowerChar.IsMatch(input))
            issues.Add(PasswordPolicyIssue.MustHaveSmallLetter);

        if (!hasUpperChar.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustHaveCapitalLetter);

        if (!hasMinChars.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustBeAtLeast8Characters);

        if (!hasNumber.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustHaveNumber);

        if (!hasSymbols.IsMatch(input))
             issues.Add(PasswordPolicyIssue.MustHaveSymbol);
        
        return issues.Count() ==0;
}

Original answer by @Anurag

答案 12 :(得分:-1)

May be try this:

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

Also, you can use this page to check regular expressions:

http://rubular.com/r/ckRwasekcd