Dynadot

Password Strength PHP Class

Spaceship Spaceship
Watch

xrvel

i love automationVIP Member
Impact
163
Here is a class to measure how good a password is (with my own algorithm lol). Not sure what is the benefit of this on the future :)

PHP:
<?php
/**
* Password strength indicator class (BETA)
*
* Version        : 1.0.0.0
* Author        : 
* Last modified    : January 9th 2009
* Website        : http://dev.xrvel.com or http://xrvel.com
*/

class PasswordStrength {
    private $password = '';
    private $passwordFlag = array();
    private $passwordInfo = array();
    private $passwordLength = 0;
    private $scorePrecision = 2;

    function PasswordStrength() {
    }

    public function calculateAll() {
        $this->initAll();

        $this->calculateLength();
        $this->calculateComplexity();
        $this->calculateCharSetComplexity();
        ksort($this->passwordInfo);

        $this->passwordInfo['password'] = $this->password;

        $total = 0;
        $scoreCount = 0;
        $keys = array_keys($this->passwordInfo['details']);
        foreach ($keys as $key) {
            if (preg_match('/Score+$/', $key)) {
                $total += intval($this->passwordInfo['details'][$key]);
                $scoreCount ++;
            }
        }
        $averageScore = round($total / $scoreCount, $this->scorePrecision);
        $scoreInfo = $this->getScoreInfo($averageScore);

        $this->passwordInfo['totalScore'] = $total;
        //$this->passwordInfo['scoreCount'] = $scoreCount;
        $this->passwordInfo['averageScore'] = $averageScore;
        $this->passwordInfo['averageScoreInfo'] = $scoreInfo;
    }

    public function getInfo() {
        return $this->passwordInfo;
    }

    public function setPassword($password) {
        $this->password = $password;
        $this->passwordLength = strlen($password);
    }

    /////////////////////////

    private function calculateCharSetComplexity() {
        $password = $this->password;
        $len = strlen($password);
        $char = '';
        $lastChar = '';
        $differentCount = 0;
        $score = 0;

        if ($len <= 3) {
            $score = 2;
        } else {
            for ($i = 0; $i < $len; $i++) {
                $char = substr($password, $i, 1);
                if ($i > 0) {
                    $lastChar = substr($password, $i-1, 1);
                }
   
                if ($char != $lastChar) {// current char is different with the previous char
                    $differentCount++;
                }
            }
            if ($len <= 5) {
                $score = 10;
            } else if ($differentCount == 1) {// only one character type
                $score = 1;
                // adjust length score
                $this->passwordInfo['details']['lengthScore'] = min(min(floor(10 * $this->passwordLength / 10), 20), $this->passwordInfo['details']['lengthScore']);
            } else if ($differentCount == 2) {// only one character type
                $score = 5;
                // adjust length score
                $this->passwordInfo['details']['lengthScore'] = min(min(floor(20 * $this->passwordLength / 10), 40), $this->passwordInfo['details']['lengthScore']);
            } else if ($differentCount == 3) {// only one character type
                $score = 10;
                // adjust length score
                $this->passwordInfo['details']['lengthScore'] = min(min(floor(30 * $this->passwordLength / 10), 50), $this->passwordInfo['details']['lengthScore']);
            } else {
                $score = round(max($this->passwordInfo['details']['lengthScore'] / 10, $differentCount / $len * 100), $this->scorePrecision);
            }
        }

        $this->passwordInfo['details']['characterSetComplexityScore'] = $score;
    }

    private function calculateComplexity() {
        $password = $this->password;
        $score = 0;
        if (preg_match('/^([0-9]+)+$/', $password)) {// only numerics
            $score = 10;
            $this->passwordFlag['charSet'] = 'numeric';
        } else if (preg_match('/^([a-z]+)+$/', $password)) {// only alpha
            $score = 30;
            $this->passwordFlag['charSet'] = 'alpha';
        } else if (preg_match('/^([a-z0-9]+)+$/i', $password)) {// if alpha numeric
            if (preg_match('/^([a-z]+)([0-9]+)+$/i', $password, $match)) {// if alpha and followed by numerics
                $alpha = $match[1];
                $numeric = $match[2];
                $numericLength = strlen($numeric);
                if ($numeric == 111 || $numeric == 123) {
                    $score = 31;
                    $this->passwordFlag['commonNumeric'] = true;
                } else if ($numericLength == 1) {
                    $score = 30;
                } else if ($numericLength <= 3) {
                    $score = 35;
                } else if ($numericLength <= 5) {
                    $score = 40;
                } else if ($numericLength <= 10) {
                    $score = 50;
                } else {
                    $score = 60;
                }
                $this->passwordFlag['charSet'] = 'alphanumeric1';
            } else if (preg_match('/^([0-9]+)([a-z]+)+$/i', $password, $match)) {// if numerics and followed by alpha
                $numeric = $match[1];
                $alpha = $match[2];
                $numericLength = strlen($numeric);
                if ($numeric == 111 || $numeric == 123) {
                    $score = 35;
                    $this->passwordFlag['commonNumeric'] = true;
                } else if ($numericLength == 1) {
                    $score = 30;
                } else if ($numericLength <= 3) {
                    $score = 35;
                } else if ($numericLength <= 5) {
                    $score = 40;
                } else if ($numericLength <= 10) {
                    $score = 50;
                } else {
                    $score = 60;
                }
                $this->passwordFlag['charSet'] = 'alphanumeric2';
            } else {// mixed positions
                $score = 80;
                $this->passwordFlag['charSet'] = 'alphanumeric3';
            }
        } else {
            $score = 100;
            $this->passwordFlag['charSet'] = 'alphanumericothers';
        }
        $this->passwordInfo['details']['characterSetScore'] = $score;
    }

    private function calculateLength() {
        $len = strlen($this->password);
        $score = 0;
        if ($len == 0) {
            //
        } else if ($len <= 3) {
            $score = 1;
        } else if ($len <= 4) {
            $score = 2;
        } else if ($len <= 5) {
            $score = 10;
        } else if ($len <= 6) {
            $score = 20;
        } else if ($len <= 8) {
            $score = 30;
        } else if ($len <= 10) {
            $score = 45;
        } else if ($len <= 15) {
            $score = 75;
        } else if ($len <= 18) {
            $score = 80;
        } else if ($len <= 20) {
            $score = 90;
        } else {
            $score = 100;
        }
        $this->passwordInfo['details']['lengthScore'] = $score;
    }

    private function getScoreInfo($score) {
        if ($score <= 15) {
            $scoreInfo = 'Very Bad';
        } else if ($score <= 35) {
            $scoreInfo = 'Bad';
        } else if ($score <= 45) {
            $scoreInfo = 'Medium - Bad';
        } else if ($score <= 55) {
            $scoreInfo = 'Medium';
        } else if ($score <= 65) {
            $scoreInfo = 'Medium - Good';
        } else if ($score <= 75) {
            $scoreInfo = 'Good';
        } else if ($score <= 90) {
            $scoreInfo = 'Very Good';
        } else if ($score <= 100) {
            $scoreInfo = 'Excellent';
        }
        return $scoreInfo;
    }

    private function initAll() {
        $this->passwordFlag = array();
        $this->passwordInfo = array();
        //$this->passwordLength = 0;
    }
}
?>

Here is an example
PHP:
<?php
$p = '';
if (isset($_POST['p'])) {
    $p = $_POST['p'];
}

require('../passwordstrength.class.php');
$ps = new PasswordStrength();
?>
<h1>Password Strength Calculator</h1>
<form method="post" action="<?php echo basename(__FILE__); ?>">
Password = <input type="text" name="p" value="<?php echo $p; ?>" />
<input type="submit" value="Calculate Strength" /> <input type="reset" />
</form>
<pre>
<?php
if ($p != '') {
    $ps->setPassword($p);
    $ps->calculateAll();
    $info = $ps->getInfo();
    print_r($info);
    echo '<hr />';
}

$ps->setPassword('aaaaa');
$ps->calculateAll();
$info = $ps->getInfo();
print_r($info);

$ps->setPassword('1203810293');
$ps->calculateAll();
$info = $ps->getInfo();
print_r($info);

$ps->setPassword('aaaa3');
$ps->calculateAll();
$info = $ps->getInfo();
print_r($info);

$ps->setPassword('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3');
$ps->calculateAll();
$info = $ps->getInfo();
print_r($info);

$ps->setPassword('hello1');
$ps->calculateAll();
$info = $ps->getInfo();
print_r($info);

$ps->setPassword('aaaaa123');
$ps->calculateAll();
$info = $ps->getInfo();
print_r($info);

$ps->setPassword('a5aaaa123');
$ps->calculateAll();
$info = $ps->getInfo();
print_r($info);
?>
</pre>

Output sample
Code:
Array
(
    [details] => Array
        (
            [lengthScore] => 10
            [characterSetScore] => 30
            [characterSetComplexityScore] => 10
        )

    [password] => aaaaa
    [totalScore] => 50
    [averageScore] => 16.67
    [averageScoreInfo] => Bad
)
Array
(
    [details] => Array
        (
            [lengthScore] => 45
            [characterSetScore] => 10
            [characterSetComplexityScore] => 100
        )

    [password] => 1203810293
    [totalScore] => 155
    [averageScore] => 51.67
    [averageScoreInfo] => Medium
)
Array
(
    [details] => Array
        (
            [lengthScore] => 10
            [characterSetScore] => 30
            [characterSetComplexityScore] => 10
        )

    [password] => aaaa3
    [totalScore] => 50
    [averageScore] => 16.67
    [averageScoreInfo] => Bad
)
Array
(
    [details] => Array
        (
            [lengthScore] => 40
            [characterSetScore] => 30
            [characterSetComplexityScore] => 5
        )

    [password] => aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3
    [totalScore] => 75
    [averageScore] => 25
    [averageScoreInfo] => Bad
)
Array
(
    [details] => Array
        (
            [lengthScore] => 20
            [characterSetScore] => 30
            [characterSetComplexityScore] => 83.33
        )

    [password] => hello1
    [totalScore] => 133
    [averageScore] => 44.33
    [averageScoreInfo] => Medium - Bad
)
Array
(
    [details] => Array
        (
            [lengthScore] => 30
            [characterSetScore] => 31
            [characterSetComplexityScore] => 50
        )

    [password] => aaaaa123
    [totalScore] => 111
    [averageScore] => 37
    [averageScoreInfo] => Medium - Bad
)
Array
(
    [details] => Array
        (
            [lengthScore] => 45
            [characterSetScore] => 80
            [characterSetComplexityScore] => 66.67
        )

    [password] => a5aaaa123
    [totalScore] => 191
    [averageScore] => 63.67
    [averageScoreInfo] => Medium - Good
)
 
Last edited by a moderator:
0
•••
The views expressed on this page by users and staff are their own, not those of NamePros.
Nice work there xrvel....great script :)
 
0
•••
0
•••
really nice one ;) i've found on internet some but this one is cool ;) good job!
 
0
•••
Thank you xrvel

Thank you for the detailed functionality, I have implemented it as the password strength functionality companion to a Random Password Generator API I have made available at my site. I have given you full credit and provided a link-back.

Thanks again,
TomRed
 
0
•••
very nice! :) Thank you for posting.
 
0
•••
Excellent work brother, thanks for sharing!
 
0
•••
  • The sidebar remains visible by scrolling at a speed relative to the page’s height.
Back