开发者

Password strength validator, how would you improve this?

开发者 https://www.devze.com 2023-04-07 02:48 出处:网络
First of all, I am validating password length with StringLength validator so I want to keep that out of the PasswordStrength validator. Any ideas how to improve this?

First of all, I am validating password length with StringLength validator so I want to keep that out of the PasswordStrength validator. Any ideas how to improve this?

I think my approach with arrays and array_diff is not very elegant but the only other way I can think of are regular expressions which is even more ugly.

<?php
class My_Validate_PasswordStrength extends Zend_Validate_Abstract
{
    const MSG_NO_NUMBER = 'msgNoNumber';
    const MSG_NO_LOWER_CASE_LETTER = 'msgNoLowerCaseLetter';
    const MSG_NO_UPPER_CASE_LETTER = 'msgNoUpperCase开发者_运维技巧Letter';

    protected $_messageTemplates = array(
        self::MSG_NO_NUMBER => "'%value%' must contain at least one number",
        self::MSG_NO_LOWER_CASE_LETTER => "'%value%' must contain at least one lower case letter",
        self::MSG_NO_UPPER_CASE_LETTER => "'%value%' must contain at least one upper case letter"
    );

    public function isValid($value)
    {
        $this->_setValue($value);

        $arr = str_split($value);
        $numbers = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
        $lowerCaseLetters = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 
        'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
        $upperCaseLetters = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 
        'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');

        if (count(array_diff($numbers, $arr)) === 10) {
            $this->_error(self::MSG_NO_NUMBER);
            return FALSE;
        }

        if (count(array_diff($lowerCaseLetters, $arr)) === 26) {
            $this->_error(self::MSG_NO_LOWER_CASE_LETTER);
            return FALSE;
        }

        if (count(array_diff($upperCaseLetters, $arr)) === 26) {
            $this->_error(self::MSG_NO_UPPER_CASE_LETTER);
            return FALSE;
        }

        return TRUE;
    }
}


I don't think regular expressions have to be ugly.

public function isValid($value)
{
    $this->_setValue($value);

    if (preg_match('/[0-9]/', $value) !== 1) {
        $this->_error(self::MSG_NO_NUMBER);
        return FALSE;
    }

    if (preg_match('/[a-z]/', $value) !== 1) {
        $this->_error(self::MSG_NO_LOWER_CASE_LETTER);
        return FALSE;
    }

    if (preg_match('/[A-Z]/', $value) !== 1) {
        $this->_error(self::MSG_NO_UPPER_CASE_LETTER);
        return FALSE;
    }

    return TRUE;
}


How about these tests to improve strength? At a customer we had the requirement "passwords must contain at least 1 number, 2 capital letters, at least 1 'special character' and be longer than 8 characters"

These expressions count each of those requirements - the third counting all non letters/numbers

$capCount  = preg_match_all("/[A-Z]/", $newPassword, $matches);
$numCount  = preg_match_all("/[0-9]/", $newPassword, $matches);
$specCount = preg_match_all("/[^0-9a-zA-z]/", $newPassword, $matches);
0

精彩评论

暂无评论...
验证码 换一张
取 消