密码强度验证的正则表达式

7
我已经写了一个正则表达式,可以用于密码强度验证:
^(?:([A-Z])*([a-z])*(\d)*(\W)*){8,12}$

表达式由四个组成部分组成:
  1. 零个或多个大写字母
  2. 零个或多个小写字母
  3. 零个或多个十进制数字
  4. 零个或多个非单词字符(!、£、$、%等)
我希望它的工作方式是确定已匹配的组数,以确定密码的强度。例如,如果只匹配了1个组,那么它将很弱。如果所有四个组都匹配了,那么它将很强。
我使用Rubular(一个Ruby正则表达式编辑器)测试了表达式。
在这里,我可以直观地看到有多少组被匹配,但我想在JavaScript中做到这一点。我编写了一个返回匹配组数的脚本,但结果与我在Rubular中看到的结果不同。
我如何在JavaScript中实现这一点?我的正则表达式是否能胜任?

1
你的正则表达式允许无限长度的密码,{8,12}没有任何影响。硬编码非单词字符以允许它们。我猜你想要类似于 ^[A-Za-z0-9!_.-]{8,12}$ 这样的东西。 - sp00m
“但结果不同”:以什么方式?请包括两组结果和您用于生成这些结果的代码。 - Richard
1
请注意,您的表达式仅在大写字母之后检查小写字母;然后是数字;... 它还没有将下划线视为非字母数字字符。 - Richard
参考 - 密码验证 可能会对你有所帮助。 - ctwheels
6个回答

11

我认为你需要独立检查每个组。伪代码:

bool[] array = {};
array[0] = pwd.match(/[A-Z]/);
array[1] = pwd.match(/[a-z]/);
array[2] = pwd.match(/\d/);
array[3] = pwd.match(/[!_.-]/);

int sum = 0;
for (int i=0; i<array.length; i++) {
    sum += array[i] ? 1 : 0;
}

switch (sum) {
    case 0: print("weird..."); break;
    case 1: print("weak"); break;
    case 2: print("ok"); break;
    case 3: print("strong"); break;
    case 4: print("awesome"); break;
    default: print("weird..."); break;
}

5

以下是基于sp00m答案的最终解决方案:

function testPassword(pwString) {
    var strength = 0;

    strength += /[A-Z]+/.test(pwString) ? 1 : 0;
    strength += /[a-z]+/.test(pwString) ? 1 : 0;
    strength += /[0-9]+/.test(pwString) ? 1 : 0;
    strength += /[\W]+/.test(pwString) ? 1 : 0;

    switch(strength) {
        case 3:
            // its's medium!
            break;
        case 4:
            // it's strong!
            break;
        default:
            // it's weak!
            break;
    }
}

我仅添加此内容作为参考,但是我接受了 sp00m 的答案,因为正是他们的答案让我找到了这个解决方案。

1

请查看这个链接: http://jsfiddle.net/43tu58jf/

function isSimpleStrongLevel(password){
    var stringsOptions = ['123456', '123abc', 'abc123', '654321', '012345', 'password', '123pass', 'pass123', '123456abc'];
    return stringsOptions.indexOf(password) != -1;
}
function getStrongLevel(password) {
    var level = 0;
    level += password.length > 6 ? 1 : 0;
    level += /[!@#$%^&*?_~]{2,}/.test(password) ? 1 : 0;
    level += /[a-z]{2,}/.test(password) ? 1 : 0;
    level += /[A-Z]{2,}/.test(password) ? 1 : 0;
    level += /[0-9]{2,}/.test(password) ? 1 : 0;
    return level;
}

var password = '123456';
var isSimple = isSimpleStrongLevel(password);
var level = getStrongLevel(password);
console.log(isSimple, level);

1
你可以将每个组分开并逐一匹配,像这样:
var level = 0;
var input = '';//user input goes here
switch(true){
    case /^(?:([A-Z])*){8,12}$/.test(input):
    level = 1;
    break;

    case /^(?:([A-Z])*([a-z])*){8,12}$/.test(input):
    level = 2;
    break;

    case /^(?:([A-Z])*([a-z])*(\d)*){8,12}$/.test(input):
    level = 3;
    break;

    case /^(?:([A-Z])*([a-z])*(\d)*(\W)*){8,12}$/.test(input):
    level = 4;
    break;
}

变量level的取值范围从1(最弱)到4(最强)。

0

我的例子

JS/jQuery

$( "#password" ).change(function ()
{
    strongPassword();
});

/**
 * @author websky
 */
function strongPassword() {
    var p = document.getElementById('password').value;
    var label1 = 0; 
    var label2 = 0; 
    var label3 = 0; 
    var label4 = 0; 
    var label5 = 0;
    if (p.length > 6) {//min length
        label1 = 1;
    }
    if (/[!@#$%^&*?_~]{2,}/.test(p)) {//min 2 special characters
        label2 = 1;
    }
    if (/[a-z]{2,}/.test(p)) {//min 2 a-z
        label3 = 1;
    }
    if (/[A-Z]{2,}/.test(p)) {//min 2 A-Z
        label4 = 1;
    }
    if (/[0-9]{2,}/.test(p)) {//min 2 0-9
        label5 = 1; 
    }

    var strong_password = label1 + label2 + label3 + label4 + label5;

    if(strong_password > 0){
        //Here your action
        //
        //var progressbar = strong_password * 20; 
        //$( "#progressbar" ).progressbar({value: progressbar}); <== I use jQuery progessbar
    } 
}

0
尝试一下 ==>
var PasswordStrength = function () {
    var p_worker = {
        checkMark: function ( msg, mark ) {
            let strength = "Required!!!", status = true;
            switch ( mark ) {
                case 1: strength = '<b style="color:rgb(200, 200, 200)"> Password strength: Weak...</b>'; break;
                case 2: strength = '<b style="color:rgb(200, 200, 200)"> Password strength: Semi-weak...</b>'; break;
                case 3: strength = '<b style="color:green"> Password strength: Medium...</b>'; break;
                case 4: strength = '<b style="color:green"> Password strength: Strong...</b>'; break;
                default: status = false; break;
            }
            return { status: status/*[is valid or not]*/, cur_strength: strength/**[strength msg]*/, req_msg: msg/**[required msg]*/, mark: mark/**[strength mark]*/ };
        },
        setting: {
            n: { rgx: /[0-9]/, msg: '1 Numeric character' },
            c: { rgx: /[A-Z]/, msg: '1 Alphabet character' },
            s: { rgx: /[a-z]/, msg: '1 Small character' },
            sp: { rgx: /[@#$\.%^&+=]/, msg: '1 Special character' },
        }
    };
    return {
        check: function ( value ) {
            let msg = "", mark = 0, c = 0;
            for ( let i in p_worker.setting ) {
                if ( !p_worker.setting[i]['rgx'].test( value ) ) {
                    if ( c === 3 ) {
                        msg += '<d style="color:rgba(219, 177, 177, 0.96)">[*] ' + p_worker.setting[i]['msg'] + '</d>';
                        c++; continue;
                    }
                    msg += '<d style="color:rgba(219, 177, 177, 0.96)">[*] ' + p_worker.setting[i]['msg'] + ',</d></br>';
                    c++; continue;
                }
                if ( c === 3 ) {
                    msg += '<img src="/image/accept.png" /> <d style="color:green">' + p_worker.setting[i]['msg'] + '</d>';
                    mark++; c++; continue;
                }
                msg += '<img src="/image/accept.png" /> <d style="color:green">' + p_worker.setting[i]['msg'] + ',</d></br>';
                mark++; c++;
            }
            return p_worker.checkMark( msg, mark );
        }
    }
}();

使用 ==>

PasswordStrength.check( "1234$#" );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接