【问题标题】:Password checking RegEx that matches multiple criteria匹配多个条件的密码检查正则表达式
【发布时间】:2012-11-12 20:53:49
【问题描述】:

在 Google 上进行了广泛搜索后,我遇到了一个问题。我正在尝试根据我在 SO 上找到的正则表达式编写一个正则表达式

  1. 字符串必须是8-24个字符,并且

  2. 字符串除了长度外,还需要满足以下两个条件(最少):

    • 大写
    • 小写
    • 数字
    • 非字母数字

这是我一直在尝试修改的正则表达式:

^.*(?=.{8,24})(?=.*\d|\W)(?=.*[a-zA-Z]).*$

我需要修改它以确保密码符合上述条件。

我不能进入并以编程方式执行此操作,因为它会改变我们某些代码工作方式的其他基本原理。现在我们已经进行了正则表达式检查,所以我所要做的就是使用新表达式更新配置文件。

【问题讨论】:

  • 我可以问一下,做有问题的做法会如何改变其他基本面?正则表达式并不是真正为 2/4 条件逻辑而构建的。
  • 过于严格的密码策略很容易适得其反:(例如:人们只会将它们写在他们计算机旁边的便签上,或者会忘记它们,给他们带来挫败感和问题) .
  • 要更改代码,我必须更新我们的许多服务器。要使用正则表达式,我更改一个设置并立即传播
  • 回答问题本身;是的,您可以修改正则表达式,但它会很难看。更改代码会更好。

标签: .net regex visual-studio


【解决方案1】:

也许尝试类似(删除空格)

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

结构如下:

^<char restrictions><length restriction>$

在哪里

char restriction = (<lower> and (<upper> or <numeric> or <non-alphanum>)) 
                  or (<upper> and (<numeric> or <non-alphanum>))
                  or (<numeric> and <non-alphanum>)

(所有这些都是前瞻。)

长度限制不是前瞻,因为我们需要告诉正则表达式引擎在字符串的开头和结尾之间应该有 8 到 24 个字符。 (通过将.* 放在顶层的任何位置,我们将失去执行此限制的能力。)


但是,应该尽一切努力更改代码,而不是使用这种可怕的正则表达式。

【讨论】:

  • OP 暗示更改代码以允许此更改将需要大量代码更改。这告诉我代码的结构方式可能是错误的。
  • +1 是的,这个可以解决问题。但是(?=[^A-Z]*[A-Z])(?=.*[A-Z]) 更有效率。
  • 这很微妙,但这应该以 \z 而不是 $ 结尾,否则用户最多可以输入 25 个字符。 "x\n" 匹配 "^.$" :)
【解决方案2】:

不,它不是很漂亮,但是您可以像这样使用蛮力使用单个正则表达式有效地做到这一点(假设 C#):

正则表达式匹配 4 个密码条件中的 2 个:

Regex re = new Regex(@"
    # Match 2 of 4 passwords criteria and length from 8 to 24.
    ^                   # Anchor to start of string.
    (?:                 # Group acceptable pair alternatives.
      (?=[^A-Z]*[A-Z])  # At least one Upper Case.
      (?=[^a-z]*[a-z])  # At least one Lower Case.
    |                   # or...
      (?=[^A-Z]*[A-Z])  # At least one Upper Case.
      (?=[^0-9]*[0-9])  # At least one Numeric.
    |                   # or...
      (?=[^A-Z]*[A-Z])  # At least one Upper Case.
      (?=\w*\W)         # At least one Non-AlphaNumeric.
    |                   # or...
      (?=[^a-z]*[a-z])  # At least one Lower Case.
      (?=[^0-9]*[0-9])  # At least one Numeric.
    |                   # or...
      (?=[^a-z]*[a-z])  # At least one Lower Case.
      (?=\w*\W)         # At least one Non-AlphaNumeric.
    |                   # or...
      (?=[^0-9]*[0-9])  # At least one Numeric.
      (?=\w*\W)         # At least one Non-AlphaNumeric.
    )                   # Brute force!
    .{8,24}             # Match from 8 to 24 chars.
    \z                  # Anchor to end of string.
    ", RegexOptions.IgnorePatternWhitespace);
if (re.IsMatch(text)) {
    // Password is valid.
} else {
    // Password is NOT valid.
} 

4 个要求中的 2 个有六种可能的组合。最后的.{8,24} 长度检查假定除换行符以外的任何字符都可以(您可能/应该要修改它)。

编辑:我现在看到 dbaupp 的答案工作得很好(我给了它我的赞成票)。虽然我查找大写字母的表达式:(?=[^A-Z]*[A-Z]) 比:(?=.*[A-Z]) 更有效(其他前瞻也是如此)。另一方面,dbaupp 的回答在分组方面效率更高。

【讨论】:

    【解决方案3】:
    def check_password_strength(x):
        ## Initialize the toggle flags to check 3 conditions - Capital Letter/Small Letter/Numeric Value
        flag_capital_letter = 0
        flag_small_letter = 0
        flag_numerical_letter = 0
        
        ## Message strings that will be displayed to the user
        strong_pass_msg = "Strong password"
        weak_pass_msg = "Weak Password"
        
        if len(x) >= 6 and len(x) <= 12 : ## Ensure the Length of Password between [6,12], both inclusive 
            if '#' in x or '$' in x or '@' in x : ## At least one Special Character Should be in password
                for i in x:  ## Loop for parsing the string to check for 3 remaining conditions
                    if i.islower():
                        flag_small_letter = 1
                    if i.isupper():
                        flag_capital_letter = 1
                    if i.isnumeric():
                        flag_numerical_letter = 1
                ## if all three conditions are fulfilled, all flags toggle to 1
                if flag_numerical_letter == 1 and flag_capital_letter == 1 and flag_small_letter == 1:
                    return(strong_pass_msg)
                else:
                    return(weak_pass_msg)
            else:
                return(weak_pass_msg)
        else:
            return(weak_pass_msg)
        
    username = input("Enter your Username: ")
    password = input("Enter Password: ")
    check_password_strength(password)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-16
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多