And a commit that I don't know the reason of...

This commit is contained in:
2023-11-01 18:09:14 -04:00
commit 221320db35
7 changed files with 1024 additions and 0 deletions

14
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,14 @@
stages:
- deploy
deploy:
stage: deploy
image: alpine:latest
only:
- tags
tags:
- build
script:
- apk add curl
- 'curl -iL --header "Job-Token: $CI_JOB_TOKEN" --data tag=${CI_COMMIT_TAG} "${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/composer"'
environment: production

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 siteworxpro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

139
README.md Normal file
View File

@@ -0,0 +1,139 @@
## Password Strength Tester
[![Build Status](https://travis-ci.org/siteworxpro/password-strength-tool.svg?branch=master)](https://travis-ci.org/siteworxpro/password-strength-tool)
A simple and fast password strength tester inspired by WolframAlpha's Calculation
**Usage**
```php
$scorer = \Siteworx\Passwords\Scorer::score('SuperPassword!');
echo json_encode($scorer->toArray());
```
will output and is great for an ajax endpoint
```json
{
"calculatedData": {
"length": {
"value": 56,
"count": 14,
"displayName": "Length"
},
"upperCase": {
"value": 13,
"count": 2,
"displayName": "Uppercase Letters"
},
"lowerCase": {
"value": 17,
"count": 11,
"displayName": "Lowercase Letters"
},
"numbers": {
"value": 0,
"count": 0,
"displayName": "Numbers"
},
"specialChars": {
"value": 13,
"count": 1,
"displayName": "Special Characters"
},
"numbersOnly": {
"value": 0,
"count": "no",
"displayName": "Numbers Only"
},
"lettersOnly": {
"value": -10,
"count": "yes",
"displayName": "Letters Only"
},
"repeatingChars": {
"value": -1,
"count": 1,
"displayName": "Repeating Characters"
},
"reusingChars": {
"value": -4,
"count": 2,
"displayName": "Reusing Characters"
},
"conscUpperCase": {
"value": -8,
"count": 4,
"displayName": "Consecutive Upper Case"
},
"conscLowerCase": {
"value": -26,
"count": 13,
"displayName": "Consecutive Lower Case"
},
"conscNumbers": {
"value": 0,
"count": 0,
"displayName": "Consecutive Numbers"
},
"seqLetters": {
"value": 0,
"count": 0,
"displayName": "Sequential Letters"
},
"seqNumbers": {
"value": 0,
"count": 0,
"displayName": "Sequential Numbers"
}
},
"total": 50,
"strength": {
"text_value": "Poor",
"int_value": 1
}
}
```
You can also access several helper methods
```php
if ($scorer->isExcellent()) {
echo 'Your password is excellent :)';
}
if ($scorer->isPoor()) {
echo 'Your password is poor :(';
}
```
or
```php
echo 'Your Password is ' . $scorer->stringValue();
```
```
Your Password is Poor
```
**Bias**
You can also provide a bias to the scorer if you want your passwords to be scored higher or lower.
Pass in a value between -5 to 5.
```php
$scorer = \Siteworx\Passwords\Scorer::score('N0wAStrongPassword!', -5);
echo 'This password is ' . $scorer->stringValue();
$scorer = \Siteworx\Passwords\Scorer::score('N0wAStrongPassword!', 0);
echo 'This password is ' . $scorer->stringValue();
$scorer = \Siteworx\Passwords\Scorer::score('N0wAStrongPassword!', 5);
echo 'This password is ' . $scorer->stringValue();
```
```
This password is Poor
This password is Fair
This password is Very Strong
```

15
composer.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "siteworxpro/password-score",
"description": "Find a passwords strength using more complex methods",
"type": "library",
"license": "MIT",
"require": {
},
"autoload": {
"psr-4": {
"Siteworx\\Passwords\\": "src/"
}
},
"require-dev": {
}
}

22
phpunit.xml Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
>
<php>
<ini name="error_reporting" value="-1" />
<ini name="intl.default_locale" value="en" />
<ini name="intl.error_level" value="0" />
<ini name="memory_limit" value="-1" />
</php>
<testsuites>
<testsuite name="Default">
<directory suffix='Test.php'>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>

576
src/Scorer.php Normal file
View File

@@ -0,0 +1,576 @@
<?php
namespace Siteworx\Passwords;
/**
* Class Scorer
*
* @package App\Library\Utilities
*/
class Scorer
{
private const EXCELLENT_SCORE = 120;
private const VERY_STRONG_SCORE = 100;
private const STRONG_SCORE = 80;
private const FAIR_SCORE = 55;
private const POOR_SCORE = 25;
private const VERY_POOR = 0;
private const POOR = 1;
private const FAIR = 2;
private const STRONG = 3;
private const VERY_STRONG = 4;
private const EXCELLENT = 5;
private $bias = 0;
/**
* @var string
*/
private $password;
/**
* @var array
*/
private $passwordScore = [
'calculatedData' => [],
'total' => 0,
'strength' => [
'text_value' => '',
'int_value' => 1
]
];
/**
* Scorer constructor.
* @param null $p
*/
public function __construct($p = null)
{
$this->password = $p;
}
/**
* @param string $password
* @param int -5 to 5 range of a bias to apply to passwords
* @return Scorer
* @throws \Exception
*/
public static function score(string $password, int $bias = 0): Scorer
{
$scorer = new static($password);
$scorer->setBias($bias);
$scorer->scorePassword();
return $scorer;
}
/**
* @return array
*/
public function toArray(): array
{
return $this->passwordScore;
}
/**
* @return int
*/
public function getScore(): int
{
return $this->passwordScore['total'];
}
/**
* @return string
*/
public function stringValue(): string
{
return $this->passwordScore['strength']['text_value'];
}
/**
* @return int
*/
public function intValue(): int
{
return $this->passwordScore['strength']['int_value'];
}
public function isExcellent(): bool
{
return $this->passwordScore['strength']['int_value'] === self::EXCELLENT;
}
public function isVeryStrong(): bool
{
return $this->passwordScore['strength']['int_value'] === self::VERY_STRONG;
}
public function isStrong(): bool
{
return $this->passwordScore['strength']['int_value'] === self::STRONG;
}
public function isFair(): bool
{
return $this->passwordScore['strength']['int_value'] === self::FAIR;
}
public function isPoor(): bool
{
return $this->passwordScore['strength']['int_value'] === self::POOR;
}
public function isVeryPoor(): bool
{
return $this->passwordScore['strength']['int_value'] === self::VERY_POOR;
}
/**
* @param int $bias
* @throws \LogicException
*/
private function setBias(int $bias): void
{
if ($bias > 5 || $bias < -5) {
throw new \LogicException('Bias is a value of -5 to positive 5');
}
$this->bias = round(($bias ** 2) / 3 * $bias);
}
/**
* @throws \Exception
*/
private function scorePassword(): void
{
if ($this->password === null) {
throw new \InvalidArgumentException('Password Data Not Set!');
}
$this->checkLength();
$this->countUpperCase();
$this->countLowerCase();
$this->countNumbers();
$this->countSpecialChars();
$this->checkNumbersOnly();
$this->checkLettersOnly();
$this->checkRepeatingChars();
$this->checkReusingChars();
$this->checkConsecUpperCase();
$this->checkConscLowerCase();
$this->checkConsecNumbers();
$this->checkSeqLetters();
$this->checkSeqNumbers();
$total = $this->bias;
foreach ($this->passwordScore['calculatedData'] as $score) {
$total += $score['value'];
}
$this->passwordScore['total'] = $total;
$this->passwordScore['strength'] = $this->classifyPasswordScore($total);
}
/**
* Returns the basic Very Poor -> Excellent value of the score
*
* @param int $score The value of the password score
* @return array The int value and the text value of the score
*/
private function classifyPasswordScore($score): array
{
if ($score >= self::EXCELLENT_SCORE) {
return [
'text_value' => 'Excellent',
'int_value' => self::EXCELLENT
];
}
if ($score >= self::VERY_STRONG_SCORE && $score < self::EXCELLENT_SCORE) {
return [
'text_value' => 'Very Strong',
'int_value' => self::VERY_STRONG
];
}
if ($score >= self::STRONG_SCORE && $score < self::VERY_STRONG_SCORE) {
return [
'text_value' => 'Strong',
'int_value' => self::STRONG
];
}
if ($score >= self::FAIR_SCORE && $score < self::STRONG_SCORE) {
return [
'text_value' => 'Fair',
'int_value' => self::FAIR
];
}
if ($score >= self::POOR_SCORE && $score < self::FAIR_SCORE) {
return [
'text_value' => 'Poor',
'int_value' => self::POOR
];
}
return [
'text_value' => 'Very Poor',
'int_value' => self::VERY_POOR
];
}
/**
* Checks for letters that are sequential
* ie .. abcd <- BAD
* bdca <- GOOD
* Liner Grading
* -2 points per incident
*/
private function checkSeqLetters(): void
{
$i = 0;
$this->passwordScore['calculatedData']['seqLetters']['value'] = 0;
$this->passwordScore['calculatedData']['seqLetters']['count'] = 0;
$this->passwordScore['calculatedData']['seqLetters']['displayName'] = 'Sequential Letters';
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$lastChar = $this->password[$i - 1];
if ($char !== '' && !is_numeric($char) && !is_numeric($lastChar)) {
$diff = \ord($char) - \ord($lastChar);
if ($diff === 1 || $diff === -1) {
$this->passwordScore['calculatedData']['seqLetters']['value'] -= 2;
$this->passwordScore['calculatedData']['seqLetters']['count'] += 1;
}
}
$i++;
}
}
/**
* Checks for numbers that are sequential
* ie .. 1234 <- BAD
* 4213 <- GOOD
* Liner Grading
* -2 points per incident
*/
private function checkSeqNumbers(): void
{
$i = 0;
$this->passwordScore['calculatedData']['seqNumbers']['value'] = 0;
$this->passwordScore['calculatedData']['seqNumbers']['count'] = 0;
$this->passwordScore['calculatedData']['seqNumbers']['displayName'] = 'Sequential Numbers';
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$lastChar = $this->password[$i - 1];
if ($char !== '' && is_numeric($char) && is_numeric($lastChar)) {
$diff = \ord($char) - \ord($lastChar);
if ($diff === 1 || $diff === -1) {
$this->passwordScore['calculatedData']['seqNumbers']['value'] -= 2;
$this->passwordScore['calculatedData']['seqNumbers']['count'] += 1;
}
}
$i++;
}
}
/**
* Checks for consecutive use of numbers
* ie ...
* adg552 <- 55 is BAD
* adb526 <- GOOD
* Liner Grading
* -2 per incident
*/
private function checkConsecNumbers(): void
{
$i = 0;
$this->passwordScore['calculatedData']['conscNumbers']['value'] = 0;
$this->passwordScore['calculatedData']['conscNumbers']['count'] = 0;
$this->passwordScore['calculatedData']['conscNumbers']['displayName'] = 'Consecutive Numbers';
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$lastChar = $this->password[$i - 1];
if (is_numeric($char)) {
if (is_numeric($lastChar)) {
$this->passwordScore['calculatedData']['conscNumbers']['value'] -= 2;
$this->passwordScore['calculatedData']['conscNumbers']['count'] += 1;
}
}
$i++;
}
}
/**
* Checks for consecutive use of lower case
* ie ...
* AdvRffT <- ff is BAD
* AdvRf4T <- GOOD
* Liner Grading
* -2 per incident
*/
private function checkConscLowerCase(): void
{
$i = 0;
$this->passwordScore['calculatedData']['conscLowerCase']['value'] = 0;
$this->passwordScore['calculatedData']['conscLowerCase']['count'] = 0;
$this->passwordScore['calculatedData']['conscLowerCase']['displayName'] = 'Consecutive Lower Case';
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$charDec = \ord($char);
$lastChar = $this->password[$i - 1];
$charDecLast = \ord($lastChar);
if (($charDec <= 122 && $charDec >= 97) || ($charDecLast <= 122 && $charDecLast >= 97)) {
$this->passwordScore['calculatedData']['conscLowerCase']['value'] -= 2;
$this->passwordScore['calculatedData']['conscLowerCase']['count'] += 1;
}
$i++;
}
}
/**
* Checks for consecutive use of lower case
* ie ...
* AdvRRfT <- RR is BAD
* AdvRf4T <- GOOD
* Liner Grading
* -2 per incident
*/
private function checkConsecUpperCase(): void
{
$i = 0;
$this->passwordScore['calculatedData']['conscUpperCase']['value'] = 0;
$this->passwordScore['calculatedData']['conscUpperCase']['count'] = 0;
$this->passwordScore['calculatedData']['conscUpperCase']['displayName'] = 'Consecutive Upper Case';
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$charDec = \ord($char);
$lastChar = $this->password[$i - 1];
$charDecLast = \ord($lastChar);
if (($charDec <= 90 && $charDec >= 65) || ($charDecLast <= 90 && $charDecLast >= 65)) {
$this->passwordScore['calculatedData']['conscUpperCase']['value'] += -2;
$this->passwordScore['calculatedData']['conscUpperCase']['count'] += 1;
}
$i++;
}
}
/**
* Checks entire password for chars used twice or more in a row
* ie ...
* AdvRffT <- ff is BAD
* AdvRf4T <- GOOD
* Exponential Grading
* -1 per incident to the square
*/
private function checkRepeatingChars(): void
{
$i = 0;
$this->passwordScore['calculatedData']['repeatingChars']['value'] = 0;
$this->passwordScore['calculatedData']['repeatingChars']['count'] = 0;
$this->passwordScore['calculatedData']['repeatingChars']['displayName'] = 'Repeating Characters';
$iterations = 0;
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$charDec = \ord($char);
$lastChar = $this->password[$i - 1];
$charDecLast = \ord($lastChar);
if ($charDec === $charDecLast) {
$this->passwordScore['calculatedData']['repeatingChars']['value'] -= (ceil(($iterations ** 2) / 5) + 1);
$this->passwordScore['calculatedData']['repeatingChars']['count'] += 1;
$iterations++;
}
$i++;
}
}
/**
* Checks for consecutive RE-use of chars
* ie ...
* AdvRffT <- ff is BAD
* AdvRf4T <- GOOD
* Exponential Grading
* kla;sdjlfgkd <- 'd' and 'l' would be docked for being used twice
*/
private function checkReusingChars(): void
{
$i = 0;
$this->passwordScore['calculatedData']['reusingChars']['value'] = 0;
$this->passwordScore['calculatedData']['reusingChars']['count'] = 0;
$this->passwordScore['calculatedData']['reusingChars']['displayName'] = 'Reusing Characters';
while ($i < \strlen($this->password)) {
foreach (count_chars($this->password, 1) as $i => $val) {
if ($val > 1) {
$this->passwordScore['calculatedData']['reusingChars']['value'] -= $val;
$this->passwordScore['calculatedData']['reusingChars']['count'] += 1;
}
}
$i++;
}
}
/**
* Checks to see if PW is only numbers
* ie ..
* 123498774 <- BAD
*
* Flat dock of -10
*/
private function checkNumbersOnly(): void
{
$this->passwordScore['calculatedData']['numbersOnly']['value'] = 0;
$this->passwordScore['calculatedData']['numbersOnly']['count'] = 'no';
$this->passwordScore['calculatedData']['numbersOnly']['displayName'] = 'Numbers Only';
if (is_numeric($this->password)) {
$this->passwordScore['calculatedData']['numbersOnly']['value'] = -10;
$this->passwordScore['calculatedData']['numbersOnly']['count'] = 'yes';
}
}
/**
* Checks to see if PW is only letters upper or lower
* ie ..
* DFsdffwd <- BAD
*
* Flat dock of -10
*/
private function checkLettersOnly(): void
{
$this->passwordScore['calculatedData']['lettersOnly']['value'] = -10;
$this->passwordScore['calculatedData']['lettersOnly']['count'] = 'yes';
$this->passwordScore['calculatedData']['lettersOnly']['displayName'] = 'Letters Only';
$i = 0;
while ($i < \strlen($this->password)) {
if (is_numeric($this->password[$i])) {
$this->passwordScore['calculatedData']['lettersOnly']['value'] = 0;
$this->passwordScore['calculatedData']['lettersOnly']['count'] = 'no';
return;
}
$i++;
}
}
private function countUpperCase(): void
{
$i = 0;
$this->passwordScore['calculatedData']['upperCase']['value'] = 0;
$this->passwordScore['calculatedData']['upperCase']['count'] = 0;
$this->passwordScore['calculatedData']['upperCase']['displayName'] = 'Uppercase Letters';
$iterations = 0;
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$charDec = \ord($char);
if ($charDec <= 90 && $charDec >= 65) {
$this->passwordScore['calculatedData']['upperCase']['value'] += ceil(8 * (.6 ** $iterations));
$this->passwordScore['calculatedData']['upperCase']['count'] += 1;
$iterations++;
}
$i++;
}
}
/**
* Counts and scores lower case
*
* Scored by and exponential decay
* starts at 3 points per char and goes down by .7 to the iterations
*/
private function countLowerCase(): void
{
$i = 0;
$this->passwordScore['calculatedData']['lowerCase']['value'] = 0;
$this->passwordScore['calculatedData']['lowerCase']['count'] = 0;
$this->passwordScore['calculatedData']['lowerCase']['displayName'] = 'Lowercase Letters';
$iterations = 0;
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$charDec = \ord($char);
if ($charDec <= 122 && $charDec >= 97) {
$this->passwordScore['calculatedData']['lowerCase']['value'] += ceil(3 * (.7 ** $iterations));
$this->passwordScore['calculatedData']['lowerCase']['count'] += 1;
$iterations++;
}
$i++;
}
}
private function countNumbers(): void
{
$i = 0;
$this->passwordScore['calculatedData']['numbers']['value'] = 0;
$this->passwordScore['calculatedData']['numbers']['count'] = 0;
$this->passwordScore['calculatedData']['numbers']['displayName'] = 'Numbers';
$iterations = 0;
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
if (is_numeric($char)) {
$this->passwordScore['calculatedData']['numbers']['value'] += ceil(8 * (.5 ** $iterations));
$this->passwordScore['calculatedData']['numbers']['count'] += 1;
$iterations++;
}
$i++;
}
}
/**
* Counts and scores lower case
*
* Scored by and exponential decay
* starts at 13 points per char and goes down by .5^iterations
*/
private function countSpecialChars(): void
{
$i = 0;
$this->passwordScore['calculatedData']['specialChars']['value'] = 0;
$this->passwordScore['calculatedData']['specialChars']['count'] = 0;
$this->passwordScore['calculatedData']['specialChars']['displayName'] = 'Special Characters';
$iterations = 0;
while ($i < \strlen($this->password)) {
$char = $this->password[$i];
$charDec = \ord($char);
if (($charDec <= 47 && $charDec >= 33) || ($charDec <= 96 && $charDec >= 91) || ($charDec <= 126 && $charDec >= 123)) {
$this->passwordScore['calculatedData']['specialChars']['value'] += ceil(13 * (.5 ** $iterations));
$this->passwordScore['calculatedData']['specialChars']['count'] += 1;
$iterations++;
}
$i++;
}
}
/**
* Scores password length
*
* Passwords < the 8 are automatically docked -15 and scored on a lower scale
*
* Liner scale +2 for < 8
* +4 for >= 8
*/
private function checkLength(): void
{
$this->passwordScore['calculatedData']['length']['value'] = 0;
$this->passwordScore['calculatedData']['length']['count'] = 0;
$this->passwordScore['calculatedData']['length']['displayName'] = 'Length';
if (\strlen($this->password) < 8) {
$this->passwordScore['calculatedData']['length']['value'] = -15;
$i = 0;
while ($i < \strlen($this->password)) {
$this->passwordScore['calculatedData']['length']['value'] += 2;
$this->passwordScore['calculatedData']['length']['count'] += 1;
$i++;
}
} else {
$this->passwordScore['calculatedData']['length']['value'] = 0;
$i = 0;
while ($i < \strlen($this->password)) {
$this->passwordScore['calculatedData']['length']['value'] += 4;
$this->passwordScore['calculatedData']['length']['count'] += 1;
$i++;
}
}
}
}

237
tests/PasswordTest.php Normal file
View File

@@ -0,0 +1,237 @@
<?php
final class PasswordTest extends \PHPUnit\Framework\TestCase
{
public function testReturnsPasswordClass(): void
{
$password = Siteworx\Passwords\Scorer::score('APassword');
$this->assertInstanceOf(Siteworx\Passwords\Scorer::class, $password);
}
/**
* @expectedException \LogicException
*/
public function testThrowsExceptionPositive(): void
{
$password = Siteworx\Passwords\Scorer::score('APassword', 6);
}
/**
* @expectedException \LogicException
*/
public function testThrowsExceptionNegative(): void
{
$password = Siteworx\Passwords\Scorer::score('APassword', -6);
}
public function testVeryPoorCommonPasswords(): void
{
$veryPoorPasswords = [
'aaaaaaaaaaaaaabbbbbcccccddddeeeeeeeeeeeeeffffffffffffggggggggg',
'asdfgzxcv',
'P@ssword',
'111111111111222222222223333333333444455556666777888899999'
];
foreach ($veryPoorPasswords as $poorPassword) {
$password = \Siteworx\Passwords\Scorer::score($poorPassword);
$this->assertTrue($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
}
public function testPoorPasswords(): void
{
$poorPasswords = [
'P@ssword!',
'qwerasdfzxcv',
'1qaz2wsx3edc'
];
foreach ($poorPasswords as $poorPassword) {
$password = \Siteworx\Passwords\Scorer::score($poorPassword);
$this->assertFalse($password->isVeryPoor());
$this->assertTrue($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
}
public function testFairPasswords(): void
{
$fairPasswords = [
'p2vNGcbnjq79',
'N2GLVE8TwMh3',
'W4JR5Y21eDgS'
];
foreach ($fairPasswords as $fairPassword) {
$password = \Siteworx\Passwords\Scorer::score($fairPassword);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertTrue($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
}
public function testStrongPasswords(): void
{
$strongPasswords = [
'0}UVsHlMwWF^21.Q',
'9]y.GqzxsoaX8142',
'~Va.^i(,\FLt=eurHzg@W'
];
foreach ($strongPasswords as $strongPasswords) {
$password = \Siteworx\Passwords\Scorer::score($strongPasswords);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertTrue($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
}
public function testVeryStrongPasswords(): void
{
$veryStrongPasswords = [
'3+gk~X7m!aUe6JG=chzI',
',=45Dxv#M)n(\}uLpsF.',
'y7eJ5dDIH$N)#3}KMsT%'
];
foreach ($veryStrongPasswords as $veryStrongPassword) {
$password = \Siteworx\Passwords\Scorer::score($veryStrongPassword);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertTrue($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
}
public function testExcellentPasswords(): void
{
$excellentPasswords = [
'8B^2IFjN[n&ryOETRA4#1!tHe0=',
'cxbt0[YQsaw%!k#+)2LUgu?drBD',
'{9eOSN$JB!`\K3sH7*8m]rRU&xf'
];
foreach ($excellentPasswords as $excellentPassword) {
$password = \Siteworx\Passwords\Scorer::score($excellentPassword);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertTrue($password->isExcellent());
}
}
public function testBiasUp(): void
{
$fairPasswords = [
'p2vNGacbfnjq79',
'N2GLVwE8TwMdh3',
'W4dJR5Y21eaDgS'
];
foreach ($fairPasswords as $fairPassword) {
$password = \Siteworx\Passwords\Scorer::score($fairPassword);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertTrue($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
foreach ($fairPasswords as $strongNowPassword) {
$password = \Siteworx\Passwords\Scorer::score($strongNowPassword, 4);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertTrue($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
foreach ($fairPasswords as $veryStrongNowPassword) {
$password = \Siteworx\Passwords\Scorer::score($veryStrongNowPassword, 5);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertTrue($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
}
public function testBiasDown(): void
{
$fairPasswords = [
'p2vNGacbfnjq79',
'N2GLVwE8TwMdh3',
'W4dJR5Y21eaDgS'
];
foreach ($fairPasswords as $fairPassword) {
$password = \Siteworx\Passwords\Scorer::score($fairPassword);
$this->assertFalse($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertTrue($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
foreach ($fairPasswords as $poorNowPassword) {
$password = \Siteworx\Passwords\Scorer::score($poorNowPassword, -4);
$this->assertFalse($password->isVeryPoor());
$this->assertTrue($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
foreach ($fairPasswords as $veryPoorNowPassword) {
$password = \Siteworx\Passwords\Scorer::score($veryPoorNowPassword, -5);
$this->assertTrue($password->isVeryPoor());
$this->assertFalse($password->isPoor());
$this->assertFalse($password->isFair());
$this->assertFalse($password->isStrong());
$this->assertFalse($password->isVeryStrong());
$this->assertFalse($password->isExcellent());
}
}
}