Skip to content

Instantly share code, notes, and snippets.

@ve3
Last active July 14, 2019 08:10
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ve3/87b7c2aad2c102059a6840da5189df0b to your computer and use it in GitHub Desktop.
Check password hash length for each algo.
<?php
function printDebug($var)
{
echo '<pre>' . print_r($var, true) . '</pre>' . PHP_EOL;
}
/**
* Generate random string.
*
* For ASCII text only.
*
* @link https://stackoverflow.com/a/4356295/128761 Reference
* @link https://www.php.net/manual/en/language.types.string.php#language.types.string.substr PHP string bracket reference.
* @param int $length String length.
* @param string $characters The allowed characters.
* @return string Return generated random string.
*/
function randomString(int $length = 10, string $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'): string
{
if (strtolower(mb_detect_encoding($characters)) !== 'ascii') {
// if characters is not ASCII.
// use default ASCII text because PHP string index does not support multi-byte.
// @link https://www.php.net/manual/en/language.types.string.php#language.types.string.substr PHP string bracket reference.
// Warning Internally, PHP strings are byte arrays.
// As a result, accessing or modifying a string using array brackets is not multi-byte safe,
// and should only be done with strings that are in a single-byte encoding such as ISO-8859-1
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
$charactersLength = mb_strlen($characters, '8bit') - 1;
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[random_int(0, $charactersLength)];
}// endfor;
unset($charactersLength);
return $randomString;
}// randomString
/**
* Generate random unicode string.
*
* To count the length, please use `mb_strlen()` instead of `strlen()`.
*
* @link https://stackoverflow.com/a/4356295/128761 Reference
* @param int $length String length.
* @param string $characters The allowed characters.
* @return string Return generated random string.
*/
function randomUnicode(int $length = 10, string $characters = null): string
{
if (trim($characters) == null) {
// if set null to characters
// means use default.
// english, number
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
// thai
$characters .= '๐๑๒๓๔๕๖๗๘๙กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ฿';
// japanese
$characters .= '一九七二人入八力十下三千上口土夕大女子小山川五天中六円手文日月木水火犬王正出本右四左玉生田白目石立百年休先名字早気竹糸耳虫村男町花見貝赤足車学林空金雨青草音校森';
}
$charactersLength = mb_strlen($characters) - 1;
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= mb_substr($characters, random_int(0, $charactersLength), 1);
}
unset($charactersLength);
return $randomString;
}// randomUnicode
<?php
require_once 'functions.php';
echo '<h2>password algorithm &amp; hash tests</h2>' . PHP_EOL;
echo '<p>please run this test in newest php version as possible.</p>' . PHP_EOL;
if (!isset($_GET['start']) || (isset($_GET['start']) && $_GET['start'] !== 'true')) {
echo '<p>to get start please click on start below and wait.</p>' . PHP_EOL;
echo '<p><a href="?start=true">start</a></p>' . PHP_EOL;
} else {
$testLogFile = __DIR__ . DIRECTORY_SEPARATOR . 'password-tests-result.txt';
// clear old log files.
if (is_file($testLogFile)) {
unlink($testLogFile);
}
// setup password algorithm set for tests.
$passwordAlgoSet = [];
if (defined('PASSWORD_BCRYPT')) {
$passwordAlgoSet[0]['algo'] = PASSWORD_BCRYPT;
$passwordAlgoSet[0]['algoName'] = 'PASSWORD_BCRYPT';
$passwordAlgoSet[0]['options'] = ['cost' => 11];
} else {
$passwordAlgoSet[0]['algo'] = PASSWORD_DEFAULT;
$passwordAlgoSet[0]['algoName'] = 'PASSWORD_DEFAULT';
$passwordAlgoSet[0]['options'] = ['cost' => 11];
}
if (defined('PASSWORD_ARGON2I')) {
$passwordAlgoSet[1]['algo'] = PASSWORD_ARGON2I;
$passwordAlgoSet[1]['algoName'] = 'PASSWORD_ARGON2I';
$passwordAlgoSet[1]['options'] = ['memory_cost' => 3072, 'time_cost' => 50];
}
if (defined('PASSWORD_ARGON2ID')) {
$passwordAlgoSet[2]['algo'] = PASSWORD_ARGON2ID;
$passwordAlgoSet[2]['algoName'] = 'PASSWORD_ARGON2ID';
$passwordAlgoSet[2]['options'] = ['memory_cost' => 3072, 'time_cost' => 50];
}
// prepare output log.
$outputLog = 'PHP version: ' . PHP_VERSION . PHP_EOL . PHP_EOL . PHP_EOL;
$hashedLength = [];// for finding max. min length.
$passwordLengthTests = [30, 60, 100, 200, 300];// for generate password in these length.
foreach ($passwordAlgoSet as $pkey => $pitem) {
$outputLog .= 'Algorithm: ' . $pitem['algoName'] . PHP_EOL;
$outputLog .= 'Options: ' . trim(print_r($pitem['options'], true)) . PHP_EOL;
$outputLog .= 'Password generator and hash tests.' . PHP_EOL;
foreach ($passwordLengthTests as $length) {
$generatedPassResult = generateRandomPasswordWithHash($length, $pitem['algo'], $pitem['options'], $hashedLength);
$outputLog .= ' Password: ' . $generatedPassResult['password'] . '(' . mb_strlen($generatedPassResult['password']) . ')' . PHP_EOL;
$outputLog .= ' Hashed: ' . $generatedPassResult['hashedPassword'] . '(' . mb_strlen($generatedPassResult['hashedPassword']) . ')' . PHP_EOL;
$outputLog .= ' Verify: ' . trim(var_export($generatedPassResult['verifyPassword'], true)) . PHP_EOL;
$outputLog .= PHP_EOL;
}// endforeach;
unset($length);
$outputLog .= 'Min hashed: ' . min($hashedLength) . PHP_EOL;
$outputLog .= 'Max hashed: ' . max($hashedLength) . PHP_EOL;
$outputLog .= '========================================' . PHP_EOL . PHP_EOL . PHP_EOL;
$hashedLength = [];// reset
}// endforeach;
unset($pitem, $pkey);
// write to file.
file_put_contents($testLogFile, $outputLog);
unset($hashedLength, $outputLog, $passwordLengthTests);
echo 'success, please view it in the <a href="password-tests-result.txt">log file</a><br>' . PHP_EOL;
}
function generateRandomPasswordWithHash(int $length, int $passwordAlgo, array $passwordOptions = [], array &$hashedLength = []): array
{
$output = [];
$output['password'] = randomUnicode($length);
$output['hashedPassword'] = password_hash($output['password'], $passwordAlgo, $passwordOptions);
$hashedLength[] = mb_strlen($output['hashedPassword']);
$output['verifyPassword'] = password_verify($output['password'], $output['hashedPassword']);
return $output;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment