正则表达式:“密码必须至少有以下4个中的3个”

时间:2015-07-02 17:44:35

标签: regex passwords

我是一个正则表达式的新手,到目前为止只用于简单的事情,比如“必须是数字或字母”。现在我必须做一些更复杂的事情。

我需要用它来验证密码,密码必须是8-16个字符,没有控制/非打印/非ASCII字符,并且必须至少有以下三种:

  • 一个大写字母
  • 一个小写字母
  • 一个数字0-9
  • 一个符号字符($,%,&等)

我在想我要做的就是写一些大写字母,小写字母和数字,或一个大写字母,小写字母和一个符号,或一个大写字母,一个数字或一个符号,或者。 ......“涵盖所有可能的”4个中的3个“组合,但这似乎过多了。有更简单的解决方案吗?

2 个答案:

答案 0 :(得分:6)

正确的方法是分别检查所有五个条件。但是,我认为你有理由想要一个正则表达式,在这里你去:

/^((?=.*[A-Z])(?=.*[a-z])(?=.*\d)|(?=.*[a-z])(?=.*\d)(?=.*[\$\%\&])|(?=.*[A-Z])(?=.*\d)(?=.*[\$\%\&])|(?=.*[A-Z])(?=.*[a-z])(?=.*[\$\%\&])).{8,16}$/

说明:

  • 我们希望匹配整个事物,因此我们用^$
  • 包围它
  • .{n,m}匹配nm个字符(在我们的例子中为8和16)。
  • 您可以检查字符串是否包含某些内容而不实际匹配的一般方法是使用正向前瞻(?=.*X),其中X是您要检查的内容。例如,如果要确保字符串包含小写字母,则可以执行(?=.*[a-z])
  • 如果您想检查字符串是否包含XYZ,但没有实际匹配它们,您可以通过附加三个前瞻{{1来使用上一个配方}}
  • 我们使用上面的内容来匹配上述四件事中的三件。我们会使用(?=.*X)(?=.*Y)(?=.*Z)(或) - |cCD|cDS|CDS|CcS =小写字母,c =大写字母,C =数字,{{ 1}} =特殊)

See it in action

答案 1 :(得分:5)

最好的方法是分别检查每个条件。如果您尝试将所有条件标准放入一个表达式中,性能将受到影响(请参阅接受的答案)。我还强烈建议不要将密码的长度限制为16个字符 - 这对于现代标准来说是极不安全的。尝试更像64个字符,甚至更好的字符,128 - 假设你的哈希体系结构可以处理负载。

您也没有指定语言,但这是在JavaScript中执行此操作的一种方法:

$requestMethod = "GET";

$ch = curl_init();

$options = array(
    'Authorization-Code: '. AUTHORIZATION_CODE .'',
    'Client-Secret: '. CLIENT_SECRET .'',
    'Content-Type: '. CONTENT_TYPE .'',
    'Accept: '. ACCEPTS .''
);

curl_setopt ($ch, CURLOPT_CAINFO, "/xampp/htdocs/cacert.pem");
curl_setopt($ch, CURLOPT_URL, "https://api.fortnox.se/3/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, $options);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $requestMethod);

$curlResponse = curl_exec($ch);
$info = curl_getinfo($ch);

//echo 'Took ' . $info['total_time'] . ' seconds for url ' . $info['url'];

echo $curlResponse;

if ($curlResponse === FALSE) {

    echo "cURL Error: " . curl_error($ch);

}
curl_close($ch);