【问题标题】:Help with password complexity regex帮助密码复杂性正则表达式
【发布时间】:2011-02-04 15:23:31
【问题描述】:

我正在使用以下正则表达式来验证密码复杂性:

/^.*(?=.{6,12})(?=.*[0-9]{2})(?=.*[A-Z]{2})(?=.*[a-z]{2}).*$/

简而言之:2个小写,2个大写,2个数字,最小长度为6,最大长度为12。

当我使用最小长度时,它完美地工作,除了最大长度。

例如:

/^.*(?=.{6,})(?=.*[0-9]{2})(?=.*[A-Z]{2})(?=.*[a-z]{2}).*$/

这正确地要求最小长度为 6!

还有这个:

/^.*(?=.{,12})(?=.*[0-9]{2})(?=.*[A-Z]{2})(?=.*[a-z]{2}).*$/

正确地要求最大长度为 12。

但是,当我像第一个示例一样将它们配对时,它就不起作用了!!

什么给了?谢谢!

【问题讨论】:

  • 您想阻止某人拥有超过 13 个字符(因此更安全)密码的任何特定原因?
  • 有些系统实际上有一个他们可以接受的最大密码长度,我记得在我以前的unix/windows组合网络上,我们不能超过8个字符。
  • 除非不可避免的技术限制对密码长度进行硬限制(例如在@hhafez 的情况下),最佳实践绝对是不要不必要地限制密码长度(如@nickf 所说)。无论如何,您不必存储密码 - 只有它的哈希值,无论密码是 2 个字符还是 200 个字符,它的长度通常相同。
  • 感谢所有回复,在这种情况下没有特别的理由限制最大长度,它只是一个完整的例子! :)

标签: php regex validation passwords


【解决方案1】:

你想要:

/^(?=.{6,12}$)...

你正在做的是说:找到我后面的任何字符序列:

  • 6-12 个字符
  • 后跟 2 位数字的另一个字符序列
  • 后跟 2 个大写字母的另一个字符序列
  • 后跟 2 个小写字母的另一个字符序列

然后是另一个字符序列。这就是最大长度不起作用的原因,因为 30 个字符后跟 00AAaa,另外 30 个字符将通过。

你正在做的是将两个数字强制在一起。不那么严格,但要求字符串中的任何位置至少有两个数字:

/^(?=.{6,12}$)(?=(.*?\d){2})(?=(.*?[A-Z]){2})(?=(.*?[a-z]){2})/

最后你会注意到我使用的是非贪婪表达式 (.*?)。这将避免 很多 的回溯,并且对于这种验证是您通常应该使用的。区别:

(.*\d){2}

(.*?\d){2}

第一个会用.* 抓取所有字符,然后寻找一个数字。它不会找到一个,因为它会在字符串的末尾,所以它会回溯一个字符,然后寻找一个数字。如果它不是一个数字,它将继续回溯,直到找到一个。完成后,它将再次匹配整个表达式,这将触发更多的回溯。

这就是贪婪通配符的意思。

第二个版本会将零个字符传递给.*? 并寻找一个数字。如果不是数字,.*? 将抓取另一个字符,然后查找数字等等。特别是在长搜索字符串上,这可能会快几个数量级。使用简短的密码几乎肯定不会产生影响,但了解正则表达式匹配器的工作原理并尽可能编写最好的正则表达式是一个好习惯。

话虽如此,这可能是一个为自己好而过于聪明的例子。如果密码因不满足这些条件而被拒绝,您如何确定哪个密码失败,以便向用户提供有关修复什么的反馈?在实践中,编程解决方案可能更可取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    相关资源
    最近更新 更多