简体   繁体   中英

Regular Expression for Password Strength Validation

I have written a regular expression which could potentially be used for password strength validation:

^(?:([A-Z])*([a-z])*(\d)*(\W)*){8,12}$

The expression consists of four groups:

  1. Zero or more uppercase characters
  2. Zero or more lowercase characters
  3. Zero or more decimal digits
  4. Zero or more non-word characters (!, £, $, %, etc.)

The way I want it to work is to determine how many of the groups have been matched in order to determine the strength of the password. so for example, if only 1 group is matched, it would be weak. If all four groups were matched, it would be strong.

I have tested the expression using Rubular (a Ruby regular expression editor).

Here I can see visually, how many groups are matched, but I want to do this in JavaScript. I wrote a script that returns the number of matched groups, but the results were not the same as I can see in Rubular.

How can I achieve this in JavaScript? and is my regular expression up to the task?

I think you'll have to check each group independently. Pseudo-code:

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;
}

Here was my final solution based on sp00m's answer:

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;
    }
}

I've added this purely for reference, however have accepted sp00m's answer since it was their answer that let me to this solution.

You can do it by separating each group out and match them one by one, like this:

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;
}

The level variable goes from 1 (the weakest) to 4 (the strongest).

Check out this: 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);

my example

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
    } 
}

Try it ==>

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 );
        }
    }
}();

Use ==>

PasswordStrength.check( "1234$#" );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM