Cryptographically secure tokens and public identifiers for PHP, with optional Laravel integration.
farhad-arjmand/lumen-hash-generator is a Laravel package for cryptographically secure tokens and public identifiers for php, with optional laravel integration..
It currently has 0 GitHub stars and 6 downloads on Packagist (latest version v2.0.0).
Install it with composer require farhad-arjmand/lumen-hash-generator.
Discover more Laravel packages by farhad-arjmand
or browse all Laravel packages to compare alternatives.
Last updated
Generate unpredictable API tokens, invitation codes and public identifiers. Use the same small library in plain PHP, a Laravel application, or a terminal.
Version 2 is a breaking rewrite. The Composer package keeps its historical name, farhad-arjmand/lumen-hash-generator. It now generates random tokens, rather than hashing the current time. The legacy HTTP/JWT API is removed; read the migration guide before upgrading.
use FarhadArjmand\LumenHashGenerator\TokenGenerator;
use FarhadArjmand\LumenHashGenerator\TokenHasher;
$generator = new TokenGenerator();
$token = $generator->generate(prefix: 'api_'); // api_ + 32 random characters
$hasher = new TokenHasher();
$digest = $hasher->digest($token); // Store this, not the bearer token.
$valid = $hasher->verify($token, $digest); // Constant-time digest comparison.
random_bytes() and unbiased random_int(). Fails closed if randomness is unavailable.Install the stable v2 series:
composer require 'farhad-arjmand/lumen-hash-generator:^2.0'
If Packagist has not indexed the new tag yet, add the repository directly and repeat the command:
composer config repositories.hash-generator vcs https://github.com/farhad-arjmand/lumen-hash-generator
composer require 'farhad-arjmand/lumen-hash-generator:^2.0'
Requirements: PHP 8.2–8.5. The optional provider is tested with Laravel 12 (PHP 8.2+) and Laravel 13 (PHP 8.3+). Laravel 5 and the old Lumen HTTP API are not supported by this rewrite. The core can be called directly from other frameworks, including modern Lumen installations; no Lumen integration is claimed or tested.
For development from a checkout:
composer install
composer test
composer lint
php examples/basic.php
| Method | Default random input | Default output length, excluding prefix |
|---|---|---|
| generate() | 32 independent Base62 characters | 32 characters, about 190 bits |
| hex() | 32 random bytes | 64 hexadecimal characters, 256 bits |
| base64Url() | 32 random bytes | 43 URL-safe characters, 256 bits |
$generator->generate();
$generator->hex(bytes: 32, prefix: 'secret_');
$generator->base64Url(bytes: 32);
$generator->generate(26, TokenGenerator::HUMAN_READABLE, 'invite_');
$generator->batch(count: 10, prefix: 'key_');
generate() accepts 2–94 distinct printable ASCII alphabet characters, excluding spaces. Its random length must provide at least 128 bits and cannot exceed 4,096 characters. For example, a binary alphabet needs at least 128 characters; a decimal alphabet needs 39. The default alphabet and Base64URL are URL-safe; a custom alphabet is not necessarily URL-safe.
Hex/Base64URL accept 16–1,024 random bytes. Prefixes accept up to 64 ASCII letters, digits, _ or -; prefixes add no entropy. Batches accept 1–1,000 tokens. Invalid options throw InvalidArgumentException; RNG failures propagate and must not be replaced with weaker randomness.
Randomness does not guarantee uniqueness. For persistent public identifiers, add a database unique constraint and retry a bounded number of times on a collision.
$hasher = new TokenHasher();
$plainText = $generator->base64Url();
$storedDigest = $hasher->digest($plainText);
// Persist the digest alongside owner, scope, expiration and revocation metadata.
// Return the plaintext token to the owner once, over HTTPS.
if (!$hasher->verify($providedToken, $storedDigest)) {
// Reject the request.
}
Digests are 64 lowercase hexadecimal characters. verify() rejects empty tokens and malformed digests. Optional keyed storage:
$hasher = new TokenHasher(pepper: $keyFromYourSecretManager); // At least 32 bytes.
Use a high-entropy key. Key length alone does not establish key entropy. Keep it separate from the database and stable across workers. Changing it invalidates existing digests unless your application implements a versioned key rotation strategy.
This is not a password hasher, JWT issuer, encryption library or token-management service. Use password_hash()/Laravel's password hashing for passwords. Authentication, authorization, scopes, expiry, rate limiting, revocation and one-time consumption belong in your application. Do not send token values to logs, analytics, exception context or URLs. Prefer an established authentication system such as Laravel Sanctum when you need a complete API-token lifecycle.
The service provider is discovered automatically. Constructor or route injection works with the concrete classes:
use FarhadArjmand\LumenHashGenerator\TokenGenerator;
final class CreateInvitation
{
public function __construct(private TokenGenerator $tokens) {}
public function handle(): string
{
return $this->tokens->generate(26, TokenGenerator::HUMAN_READABLE, 'invite_');
}
}
Configuration is optional:
php artisan vendor:publish --tag=hash-generator-config
The published config/hash-generator.php reads HASH_GENERATOR_PEPPER. Leave it unset for plain SHA-256 token digests. Config caching is supported. Rebuild configuration and restart long-lived workers after changing a pepper. The provider never replaces Laravel's hashing configuration or Hash facade.
For an HTTP use case, see the application-owned route example. It assumes Sanctum is already configured by the host application; the package does not install or configure it.
vendor/bin/hash-generator --prefix=api_ --count=3
vendor/bin/hash-generator --format=hex --bytes=32
vendor/bin/hash-generator --format=base64url --count=2 --json
vendor/bin/hash-generator --alphabet=0123456789 --length=39
vendor/bin/hash-generator --help
Options use --name=value; --json returns an array even for one token. Without JSON, each token is a line on stdout. Exit codes: 0 success, 2 invalid arguments, 1 runtime failure. Invalid or failed requests produce no token output. Avoid redirecting stdout to shared CI logs.
CI runs unit and Laravel integration tests on PHP 8.2–8.5, checks syntax, validates Composer metadata and audits dependencies. It also checks installation into a separate plain-PHP consumer, including the Composer-installed executable. See CONTRIBUTING.md and SECURITY.md.
The randomness tests catch regressions such as the legacy time-based collisions; they are not a statistical certification of a cryptographic primitive. Security relies on PHP's operating-system-backed random functions.
MIT © Farhad Arjmand. See LICENSE.md.