注意:似乎我必须坚持一个行正则表达式,由于我使用的验证库(jquery验证引擎)
我有以下正则表达式:
((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$).{8,25})$
匹配以下内容:
Minimun of 8 characters
1 lowercase character
1 uppercase character
1 digit
1 special character
这里的问题是它接受:P@ssW0rd和Qw3rty*为有效密码。
上面的代码不应该通过验证。我想出了这两个表达,试图解决这个问题,但没有成功地将其纳入最终作品。
p[a@][s5]{2}w[o0]rd // anything with password in it including leet variants
qw[e3]rty // anything with qwerty in it including leet variant
规则应该是:不允许任何Password或Qwerty的变体出现在单词的开头或结尾
有什么想法如何把这些放在一起并使其工作吗?
你能像下面这样添加更多的否定向前看子句吗?
(?!p[a@][s5]{2}w[o0]rd) // prevents variants of "password"
(?!qw[e3]rty) // prevents variants of "qwerty"
…获取(也加入起始锚):
^((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$)(?!p[a@][s5]{2}w[o0]rd)(?!qw[e3]rty).{8,25})$
这可能不像你想的那样工作,然而——为了确保有大写字符,你必须以大小写敏感的方式匹配,但是你的"password"one_answers"qwerty"表达式只有在你以大小写不敏感的方式匹配时才会工作。您可能需要将其更改为以下内容:
^((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$)(?![pP][aA@][sS5]{2}[wW][oO0][rR][dD])(?![qQ][wW][e3][rR][tT][yY]).{8,25})$
恶心!
老实说,我建议你从根本上重新考虑一下你的战略。
- 你可以试着把"明显"的密码列入黑名单,但你永远不可能抓住所有的密码。"@5dfgHjkl"怎么样?无论你试图禁止什么,用户都可以发明一些"明显"但允许的东西。
- 对于你禁止的每一个额外的东西,你都需要提出一个错误信息,向你的客户解释他们选择的密码有什么问题。他们不会喜欢尝试猜测你的验证函数。
- 尽管您尝试强制密码强度,但它可能无法抵御将let -speak单词与数字后缀结合在一起的常见字典攻击。
如果你想尝试并鼓励更强的密码,为什么不包括当前密码强度的可视化显示,这样你的客户就可以看到他们的密码有什么问题?你甚至不需要写代码:网上有很多插件。
你可以在你的正则表达式中添加反向预测:
^((?=.*?d)(?=.*?[a-z])(?=.*?[A-Z])(?!p[a@][s5]{2}w[o0]rd$)(?!qw[e3]rty).{8,25})$
<<h3> Regex演示/h3> 您可以使用以下格式在Regex中创建'黑名单':
blacklisted_exp_1|blacklisted_exp_2| ... (original_expression)
当任何一个黑名单表达式匹配时,整个表达式将匹配,但只有当所有黑名单表达式不匹配时,原始表达式捕获组才会匹配。
在你的例子中,这将是:
qw[e3]rty|P[a@][s5]{2}W[o0]rd|((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$).{8,25})$
这里有一个更简单的例子,你可以在web控制台中尝试:
var regex = /foo|bar|([a-z]{3})/; // Matches all 3-letter words except foo and bar
"foo".match(regex); // ["foo", undefined]
"bar".match(regex); // ["bar", undefined]
"baz".match(regex); // ["baz", "baz"]