返回首页 - Notes - 2019

检测弱密码


PHP 实现

/*
 * 检测弱密码
 */
function isWeakPassword($password, $length = 6, $name = '登录密码')
{
    $message = '';

    if (empty($message) && strlen($password) < $length) {
        $message = "长度不能少于{$length}位";
    }

    if (empty($message) && !preg_match('/[a-zA-Z]/', $password)) {
        $message = '必须包含英文字母';
    }

    if (empty($message) && !preg_match('/^[a-zA-Z]+/', $password)) {
        $message = '必须以英文字母开头';
    }

    if (empty($message) && !preg_match('/[0-9]/', $password)) {
        $message = '必须包含数字';
    }

    if (empty($message)) {
        $list = range('a', 'z');
        foreach ($list as $val) {
            $m1 = $val;
            $m2 = strtoupper($val);
            if (preg_match("/{$m1}{3,}/", $password) || preg_match("/{$m2}{3,}/", $password)) {
                $message = '不能存在三个及以上连续重复的英文字母';
                break;
            }
        }
    }

    if (empty($message)) {
        $list = range(0, 9);
        foreach ($list as $val) {
            if (preg_match("/{$val}{3,}/", $password)) {
                $message = '不能存在三个及以上连续重复的数字';
                break;
            }
        }
    }

    if (empty($message)) {
        $list = range('a', 'z');
        foreach (range('a', 'x') as $key => $val) {
            $m1 = $list[$key] . $list[$key + 1] . $list[$key + 2];
            $m2 = strtoupper($m1);  // 大写
            if (preg_match("/{$m1}/", $password) || preg_match("/{$m2}/", $password)) {
                $message = '不能存在三个及以上连续的英文字母';
                break;
            }
        }
    }

    if (empty($message)) {
        $list = range(1, 7);
        foreach ($list as $val) {
            $m1 = trim($val) . trim($val + 1) . trim($val + 2);
            $m2 = strrev($m1);  // 倒序
            if (preg_match("/{$m1}/", $password) || preg_match("/{$m2}/", $password)) {
                $message = '不能存在三个及以上连续的数字';
                break;
            }
        }
    }

    return empty($message) ? false : ($name . $message);
}

ES6 实现

/*
 * 检测弱密码
 */
function isWeakPassword(password, length = 6, name = '登录密码')
{
    function range(size, startAt = 0) {
        return [...Array(size).keys()].map(i => i + startAt);
    }

    function characterRange(startChar, endChar) {
        return String.fromCharCode(...range(endChar.charCodeAt(0) - startChar.charCodeAt(0), startChar.charCodeAt(0)))
    }

    let message = '';

    if (message === '' && password.length < length) {
        message = '长度不能少于' + length + '位';
    }

    if (message === '' && !/[a-zA-Z]/.test(password)) {
        message = '必须包含英文字母';
    }

    if (message === '' && !/^[a-zA-Z]+/.test(password)) {
        message = '必须以英文字母开头';
    }

    if (message === '' && !/[0-9]/.test(password)) {
        message = '必须包含数字';
    }

    if (message === '') {
        let list = characterRange('a', 'z').split('');
        for (let val of list) {
            let m1 = val;
            let m2 = val.toUpperCase();
            let r1 = new RegExp(m1 + '{3,}');
            let r2 = new RegExp(m2 + '{3,}');

            if (r1.test(password) || r2.test(password)) {
                message = '不能存在三个及以上连续重复的英文字母';
                break;
            }
        }
    }

    if (message === '') {
        let list = range(9);
        for (let val of list) {
            let re = new RegExp(val + '{3,}');
            if (re.test(password)) {
                message = '不能存在三个及以上连续重复的数字';
                break;
            }
        }
    }

    if (message === '') {
        let list = characterRange('a', 'z').split('');
        for (let i in characterRange('a', 'x').split('')) {
            i = parseInt(i);
            let m1 = list[i] + list[i + 1] + list[i + 2];
            let m2 = m1.toUpperCase();  // 大写
            let r1 = new RegExp(m1);
            let r2 = new RegExp(m2);

            if (r1.test(password) || r2.test(password)) {
                message = '不能存在三个及以上连续的英文字母';
                break;
            }
        }
    }

    if (message === '') {
        let list = range(7, 1);
        for (let val of list) {
            let m1 = val.toString() + (val + 1).toString() + (val + 2).toString();
            let m2 = m1.split('').reverse().join('');  // 倒序
            let r1 = new RegExp(m1);
            let r2 = new RegExp(m2);

            if (r1.test(password) || r2.test(password)) {
                message = '不能存在三个及以上连续的数字';
                break;
            }
        }
    }

    return (message === '') ? false : (name + message);
}

ES5 实现

/*
 * 检测弱密码
 */
function isWeakPassword(password, length, name)
{
    function range(size, startAt) {
        if (startAt === void 0) { startAt = 0; }
        return Array.from(Array(size).keys()).slice().map(function (i) { return i + startAt; });
    }

    function characterRange(startChar, endChar) {
        return String.fromCharCode.apply(String, range(endChar.charCodeAt(0) - startChar.charCodeAt(0), startChar.charCodeAt(0)));
    }

    var message = '';

    if (!length) {
        length = 6;
    }

    if (!name) {
        name = '登录密码';
    }

    if (message === '' && password.length < length) {
        message = '长度不能少于' + length + '位';
    }

    if (message === '' && !/[a-zA-Z]/.test(password)) {
        message = '必须包含英文字母';
    }

    if (message === '' && !/^[a-zA-Z]+/.test(password)) {
        message = '必须以英文字母开头';
    }

    if (message === '' && !/[0-9]/.test(password)) {
        message = '必须包含数字';
    }

    if (message === '') {
        var list = characterRange('a', 'z').split('');
        for (var val of list) {
            var m1 = val;
            var m2 = val.toUpperCase();
            var r1 = new RegExp(m1 + '{3,}');
            var r2 = new RegExp(m2 + '{3,}');

            if (r1.test(password) || r2.test(password)) {
                message = '不能存在三个及以上连续重复的英文字母';
                break;
            }
        }
    }

    if (message === '') {
        var list = range(9);
        for (var val of list) {
            var re = new RegExp(val + '{3,}');
            if (re.test(password)) {
                message = '不能存在三个及以上连续重复的数字';
                break;
            }
        }
    }

    if (message === '') {
        var list = characterRange('a', 'z').split('');
        for (var i in characterRange('a', 'x').split('')) {
            i = parseInt(i);
            var m1 = list[i] + list[i + 1] + list[i + 2];
            var m2 = m1.toUpperCase();  // 大写
            var r1 = new RegExp(m1);
            var r2 = new RegExp(m2);

            if (r1.test(password) || r2.test(password)) {
                message = '不能存在三个及以上连续的英文字母';
                break;
            }
        }
    }

    if (message === '') {
        var list = range(7, 1);
        for (var val of list) {
            var m1 = val.toString() + (val + 1).toString() + (val + 2).toString();
            var m2 = m1.split('').reverse().join('');  // 倒序
            var r1 = new RegExp(m1);
            var r2 = new RegExp(m2);

            if (r1.test(password) || r2.test(password)) {
                message = '不能存在三个及以上连续的数字';
                break;
            }
        }
    }

    return (message === '') ? false : (name + message);
}

date:2019-07-31