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

jam*_*lla 4 regex passwords

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

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

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

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

ndn*_*kov 8

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

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

说明:

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

看到它在行动

  • 谢谢你还包括细分!我想了解正则表达式,而不是仅仅让某人为我做. (2认同)

bra*_*ipt 5

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

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

var pws = [
    "%5abCdefg",
    "&5ab",
    "%5abCdef",
    "5Bcdwefg",
    "BCADLKJSDSDFlk"
];

function pwCheck(pw) {
    var criteria = 0;
    if (pw.toUpperCase() != pw) {
        // has lower case letters
        criteria++;
    }
    if (pw.toLowerCase() != pw) {
        // has upper case letters
        criteria++;
    }
    if (/^[a-zA-Z0-9]*$/.test(pw) === false) {
        // has special characters
        criteria++;
    }
    if (/\d/.test(pw) === true) {
        // has numbers
        criteria++;
    }
    // returns true if 3 or more criteria was met and length is appropriate
    return (criteria >= 3 && pw.length >= 8 && pw.length <= 16);
}

pws.forEach(function(pw) {
    console.log(pw + ": " + pwCheck(pw).toString());
});
Run Code Online (Sandbox Code Playgroud)