hackzilla/password-generator
Hackzilla Password Generator is a PHP library for creating secure random passwords. Configure length and character sets, or generate memorable word-based passwords. Framework-agnostic, with an optional Laravel integration.
hackzilla/password-generator is a plain PHP library, not a Laravel package. There is no service provider, facade, config file, or migration to publish. You install it, wire it into your own service/container, and call it directly.
Minimal setup:
composer require hackzilla/password-generator
Look first at:
README.md for the generator examplessrc/Generator/ComputerPasswordGenerator.php for classic random passwordssrc/Generator/HumanPasswordGenerator.php for word-based passphrasessrc/Generator/HybridPasswordGenerator.php and PinPasswordGenerator.php for segmented and numeric passwordssrc/WordList/ and tests/ to understand available dictionaries and expected behaviorThe most common first use case in a Laravel app is generating a temporary password when an admin creates a user or sends an invite:
use Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator;
$generator = (new ComputerPasswordGenerator())
->setLength(16)
->setOptionValue(ComputerPasswordGenerator::OPTION_UPPER_CASE, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_LOWER_CASE, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_NUMBERS, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_SYMBOLS, false)
->setOptionValue(ComputerPasswordGenerator::OPTION_AVOID_SIMILAR, true);
$password = $generator->generatePassword();
$passwords = $generator->generatePasswords(5); // array of 5 passwords
Then hash immediately:
User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($password),
'must_change_password' => true,
]);
If all you need is a random string or a Laravel-native password, prefer Str::password() or Str::random(). This package becomes useful when you want explicit control over character sets, avoid-similar characters, PINs, or human-readable passphrases.
Do not sprinkle generator configuration throughout controllers. Create a small service that exposes named profiles:
namespace App\Services;
use Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator;
use Hackzilla\PasswordGenerator\Generator\HumanPasswordGenerator;
class PasswordService
{
public function temporary(): string
{
return (new ComputerPasswordGenerator())
->setLength(12)
->setOptionValue(ComputerPasswordGenerator::OPTION_UPPER_CASE, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_LOWER_CASE, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_NUMBERS, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_SYMBOLS, false)
->setOptionValue(ComputerPasswordGenerator::OPTION_AVOID_SIMILAR, true)
->generatePassword();
}
public function passphrase(): string
{
return (new HumanPasswordGenerator())
->setOptionValue(HumanPasswordGenerator::OPTION_MIN_WORD_LENGTH, 5)
->setOptionValue(HumanPasswordGenerator::OPTION_MAX_WORD_LENGTH, 8)
->setOptionValue(HumanPasswordGenerator::OPTION_WORD_COUNT, 4)
->setOptionValue(HumanPasswordGenerator::OPTION_WORD_SEPARATOR, '-')
->generatePassword();
}
public function pin(): string
{
return (new \Hackzilla\PasswordGenerator\Generator\PinPasswordGenerator())
->setLength(6)
->generatePassword();
}
}
Then inject PasswordService into controllers, commands, and jobs.
A config file makes password policy visible and environment-specific:
// config/password-generator.php
return [
'temporary' => [
'length' => (int) env('PASSWORD_GENERATOR_TEMPORARY_LENGTH', 12),
'symbols' => (bool) env('PASSWORD_GENERATOR_TEMPORARY_SYMBOLS', false),
],
'passphrase' => [
'words' => (int) env('PASSWORD_GENERATOR_PASSPHRASE_WORDS', 4),
'separator' => env('PASSWORD_GENERATOR_PASSPHRASE_SEPARATOR', '-'),
],
];
Cast values explicitly. Environment variables arrive as strings, and setOptionValue(..., 'false') is not the same as false.
If you want container injection, bind the generator as transient, not singleton:
use Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator;
public function register(): void
{
$this->app->bind(ComputerPasswordGenerator::class, function () {
return (new ComputerPasswordGenerator())
->setLength((int) config('password-generator.temporary.length', 16))
->setOptionValue(ComputerPasswordGenerator::OPTION_UPPER_CASE, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_LOWER_CASE, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_NUMBERS, true)
->setOptionValue(ComputerPasswordGenerator::OPTION_SYMBOLS, (bool) config('password-generator.temporary.symbols', false));
});
}
An admin-only command is useful for local seeding or emergency temporary credentials:
namespace App\Console\Commands;
use App\Services\PasswordService;
use Illuminate\Console\Command;
class GenerateTemporaryPassword extends Command
{
protected $signature = 'password:temporary {--count=1}';
protected $description = 'Generate temporary passwords';
public function handle(PasswordService $passwords): int
{
for ($i = 0; $i < (int) $this->option('count'); $i++) {
$this->line($passwords->temporary());
}
return self::SUCCESS;
}
}
Print generated passwords only to a trusted terminal. Do not write them to application logs.
If your application has a strict password policy, do not assume enabling an option guarantees at least one character from that set. Generate and validate in a loop:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;
do {
$password = app(PasswordService::class)->temporary();
} while (Validator::make(
['password' => $password],
['password' => ['required', Password::min(12)->mixedCase()->numbers()]]
)->fails());
This is especially useful when symbols are disabled but mixedCase()->numbers() is required, or when the generator selects from a combined pool rather than guaranteeing one character per selected class.
Use HumanPasswordGenerator when a person must read, type, or communicate the credential:
$passphrase = (new HumanPasswordGenerator())
->setOptionValue(HumanPasswordGenerator::OPTION_WORD_COUNT, 4)
->setOptionValue(HumanPasswordGenerator::OPTION_WORD_SEPARATOR, '-')
->generatePassword();
Use ComputerPasswordGenerator for machine-generated temporary passwords and PinPasswordGenerator only for numeric PIN flows with rate limiting.
For stronger passphrases, inject a larger custom word list via the package’s word-list interface rather than relying only on the bundled dictionary.
Generators are stateful and mutable. A fluent call such as setLength() changes the object for subsequent calls. If you register a generator as a singleton, one request can change the length or options for the next request, especially under Octane. Bind as transient, instantiate per use, or clone before mutation.
Enabling a character option does not always guarantee that class appears. Some generators build a combined character pool and pick randomly. For compliance-sensitive policies, validate the output and regenerate on failure.
Prefer setOptionValue() / setOptionValues() over setOptions(). Depending on version, setOptions() may replace the whole option map instead of merging. Setting one option at a time makes intent and defaults clearer.
Cast config and env values. (bool) env('...', false) is essential. A string "false" is truthy in PHP and can silently enable symbols or similar-character exclusion.
Symbols break more things than developers expect. Symbols can break copy/paste into shells, CSV exports, SMS messages, URLs, and hand-typed onboarding emails. For temporary human-entered passwords, disable symbols and enable avoid-similar characters. For URL-safe tokens, use Laravel’s Str::random() or a dedicated URL-safe generator instead.
Do not store generated plaintext. Hash with Hash::make() immediately. If an admin must see the password once, return it in the response and keep only the hash and a must_change_password flag.
Check the random source. The package exposes a random-generator abstraction. Confirm the default is a secure generator for your installed version and never swap in MtRandRandomGenerator or another non-cryptographic source in production. The extension point is useful in tests, where you can inject a deterministic fake.
Human passphrase entropy depends on dictionary size. Four words from a small bundled list is not equivalent to four words from a large word list. Use at least four words for temporary access and more for high-value accounts. Do not use two- or three-word passphrases as production account passwords.
generatePasswords($count) does not guarantee uniqueness. For batch generation, run array_unique() or compare against existing hashes if collisions matter, though collisions are normally very unlikely.
No Laravel integration means you own the wiring. There is no facade or published config. Keep a single PasswordService and config file, and avoid calling generator classes directly from many places.
Watch package maintenance and PHP compatibility. Check composer show hackzilla/password-generator, the latest release date, and PHP version constraints before adding it to a long-lived application. The package is MIT-licensed and focused, but it is not a Laravel-first dependency.
Extension points are the cleanest way to customize behavior. Implement the package’s RandomGeneratorInterface for deterministic tests or alternate randomness, and implement its word-list interface for a larger, domain-specific dictionary. Subclass a generator only when you need a custom character set that the built-in options cannot express.
How can I help you explore Laravel packages today?