bjeavons/zxcvbn-php
PHP port of Dropbox’s zxcvbn password strength estimator. Uses pattern matching and conservative entropy to score passwords 0–4, detect common words/names/patterns (dates, repeats, sequences, keyboard runs), and return user-friendly warnings/suggestions.
Install via Composer
composer require bjeavons/zxcvbn-php:^1.4.2
Basic Usage (Updated for Type Clarity)
use Zxcvbn\Zxcvbn;
$zxcvbn = new Zxcvbn();
$result = $zxcvbn->calculate('Tr0ub4dour&3');
factorial() now explicitly returns float (PR #75), ensuring precision in crackTimes calculations.First Use Case: Password Validation (Unchanged)
$result = $zxcvbn->calculate($password);
if ($result->score < 3) {
return back()->withErrors(['Password too weak']);
}
src/Zxcvbn.php (verify factorial() type declaration and crackTimes precision).tests/ for edge cases (e.g., factorial() with weak passwords like 'a').// Laravel Form Request Validation
public function withValidator($validator) {
$validator->after(function ($validator) {
$result = (new Zxcvbn())->calculate($this->password);
if ($result->score < 3) {
$validator->errors()->add('password', 'Password is too weak.');
}
});
}
$zxcvbn = new Zxcvbn();
$result = $zxcvbn->calculate($password);
if ($result->score < 2) {
abort(422, 'Password must meet minimum strength requirements.');
}
Validator::extend('zxcvbn', function ($attribute, $value, $parameters) {
return (new Zxcvbn())->calculate($value)->score >= (int)($parameters[0] ?? 3);
});
crackTimes with confidence due to fixed factorial() precision.
$result = $zxcvbn->calculate($password);
if ($result->crackTimes['offline_slow_hashing_1e4_per_second'] < 1e6) {
// Password is too weak for offline attacks
}
Factorial Precision Fix (NEW)
factorial() returns float, resolving potential integer overflow in crackTimes.'a' or '123456').crackTimes before/after 1.4.2:
$result = $zxcvbn->calculate('a');
logger()->debug('Offline slow hashing (fixed):', $result->crackTimes['offline_slow_hashing_1e4_per_second']);
Performance on Weak Passwords (Unchanged)
$cacheKey = 'zxcvbn:'.$password;
$result = Cache::remember($cacheKey, now()->addMinutes(5), fn() => $zxcvbn->calculate($password));
False Positives for Complex but Short Passwords (Unchanged)
strlen() if strict length is required.User Dictionary Overrides (Unchanged)
$zxcvbn->addUserDictionary(['AcmeCorp', 'ProjectX']);
crackTimes for weak passwords:
$result = $zxcvbn->calculate('password123');
logger()->debug('Crack times (float precision):', $result->crackTimes);
$matches = $result->sequence;
logger()->debug('Matched patterns:', $matches);
Custom Scoring Logic (Unchanged)
calculate() or extend the class:
class CustomZxcvbn extends Zxcvbn {
public function calculate($password) {
$result = parent::calculate($password);
// Adjust score (e.g., penalize sequential chars)
return $result;
}
}
Plugin System (Unchanged)
$zxcvbn->addPlugin(function ($password, $result) {
if (str_contains($password, '123')) {
$result->feedback->suggestions[] = 'Avoid sequential numbers';
}
return $result;
});
Localization (Unchanged)
$zxcvbn->setFeedbackMessages([
'too_short' => 'Contraseña muy corta',
]);
vendor/bjeavons/zxcvbn-php/resources/dictionaries/
factorial(): float) are now consistent.@gjcarrette fixed a type-declaration issue in factorial().
crackTimes calculations use float precision, improving accuracy for edge cases (e.g., very weak passwords).crackTimes before/after 1.4.2 for passwords like 'a' or '123456'.$result = $zxcvbn->calculate('a');
logger()->debug('Offline slow hashing (1.4.2):', $result->crackTimes['offline_slow_hashing_1e4_per_second']);
How can I help you explore Laravel packages today?