Skip to content

Random Bytes

Random Bytes generator creates cryptographically secure hexadecimal identifiers using PHP’s random_bytes() function, ideal for security tokens, session IDs, and contexts requiring strong randomness.

Random Bytes generates secure, hexadecimal identifiers:

  • Cryptographically secure: Uses PHP’s CSPRNG
  • Hexadecimal encoding: Output contains only 0-9a-f
  • Configurable byte length: Any length you need
  • Predictable output: Always bytes * 2 characters
  • Native PHP: No external dependencies

Example Random Bytes: 4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c

Generate hexadecimal strings from random bytes:

use Cline\StronglyTypedId\Generators\RandomBytesGenerator;
// Default 16 bytes = 32 hex characters
$generator = new RandomBytesGenerator();
$id = $generator->generate();
// "4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c"
// Custom byte count
$generator = new RandomBytesGenerator(bytes: 32);
$token = $generator->generate();
// "4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c1e2d3c4b5a6978869786a5b4c3d2e1f0" (64 chars)

Output is always exactly bytes * 2 characters:

// 8 bytes = 16 hex characters
$generator = new RandomBytesGenerator(bytes: 8);
echo strlen($generator->generate()); // 16
// 16 bytes = 32 hex characters (default)
$generator = new RandomBytesGenerator(bytes: 16);
echo strlen($generator->generate()); // 32
// 32 bytes = 64 hex characters
$generator = new RandomBytesGenerator(bytes: 32);
echo strlen($generator->generate()); // 64
// 32-byte (256-bit) security token
$generator = new RandomBytesGenerator(bytes: 32);
$securityToken = $generator->generate();
// "4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c1e2d3c4b5a6978869786a5b4c3d2e1f0"
// 20-byte session identifier
$generator = new RandomBytesGenerator(bytes: 20);
$sessionId = $generator->generate();
// "4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c1e2d3c4b" (40 chars)
// 16-byte CSRF token
$generator = new RandomBytesGenerator(bytes: 16);
$csrfToken = $generator->generate();
// "4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c" (32 chars)
// 32-byte (256-bit) encryption key
$generator = new RandomBytesGenerator(bytes: 32);
$encryptionKey = $generator->generate();

Create strongly-typed random bytes IDs:

use Cline\StronglyTypedId\Generators\RandomBytesGenerator;
use Cline\StronglyTypedId\ValueObjects\StronglyTypedId;
final readonly class SecurityToken extends StronglyTypedId
{
protected static function generator(): IdGeneratorInterface
{
return new RandomBytesGenerator(bytes: 32);
}
}
// Usage
$token = SecurityToken::generate();
echo $token; // "4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c1e2d3c4b5a6978869786a5b4c3d2e1f0"

Use with Eloquent models:

use Illuminate\Database\Eloquent\Model;
class SecureToken extends Model
{
protected $casts = [
'token' => SecurityToken::class,
];
protected static function booted(): void
{
static::creating(function (SecureToken $token) {
$token->token = SecurityToken::generate();
});
}
}

Migration:

Schema::create('secure_tokens', function (Blueprint $table) {
$table->id();
$table->string('token', 64)->unique(); // 32 bytes = 64 hex chars
$table->timestamp('expires_at');
$table->timestamps();
});

Create prefixed hexadecimal IDs:

use Cline\StronglyTypedId\Generators\PrefixedIdGenerator;
use Cline\StronglyTypedId\Generators\RandomBytesGenerator;
// Security token with prefix
$generator = new PrefixedIdGenerator(
'sec',
new RandomBytesGenerator(bytes: 32)
);
$secToken = $generator->generate();
// "sec_4f3b7c2a8e1d9f6b5a3c8e2d7f1b4a9c1e2d3c4b5a6978869786a5b4c3d2e1f0"
  • Uses PHP’s random_bytes() function
  • Cryptographically secure pseudo-random number generator (CSPRNG)
  • Platform-dependent source (e.g., /dev/urandom on Unix)

Hexadecimal provides 4 bits per character:

BytesHex CharsEntropySecurity Level
81664 bitsBasic
1632128 bitsStandard
3264256 bitsHigh
64128512 bitsMaximum
Use CaseBytesHex LengthEntropy
CSRF Tokens1632128 bits
Session IDs2040160 bits
API Tokens3264256 bits
Encryption Keys3264256 bits
Master Secrets64128512 bits

Store as fixed-length CHAR or VARCHAR:

Schema::create('tokens', function (Blueprint $table) {
// 16 bytes = 32 hex characters
$table->char('token', 32)->unique();
// 32 bytes = 64 hex characters
$table->char('secure_token', 64)->unique();
$table->timestamps();
});

Binary storage for space efficiency:

// Store as binary instead of hex string
Schema::create('tokens', function (Blueprint $table) {
$table->binary('token', 32)->unique(); // 32 bytes raw
$table->timestamps();
});
// Custom casting
protected $casts = [
'token' => 'binary',
];
// 32 bytes = 64 character hex string
$table->char('token', 64);
// Pros: Human-readable, easy to debug
// Cons: 2x storage space
// 32 bytes = 32 byte binary
$table->binary('token', 32);
// Pros: 50% storage savings
// Cons: Not human-readable
  • Random Bytes: Hexadecimal (16 chars), predictable length
  • Random String: Alphanumeric (62 chars), configurable
  • Random Bytes: Configurable length, no structure
  • UUID: Fixed 36-char format, version metadata
  • Random Bytes: Hex only, higher entropy per char
  • NanoID: URL-safe alphabet, more compact
use Illuminate\Support\Facades\Hash;
$generator = new RandomBytesGenerator(bytes: 32);
$plainToken = $generator->generate();
// Hash before storage
$hashedToken = Hash::make($plainToken);
// Prevent timing attacks
if (hash_equals($storedToken, $providedToken)) {
// Valid token
}
Schema::create('tokens', function (Blueprint $table) {
$table->char('token', 64)->unique();
$table->timestamp('expires_at')->index();
});
// Clean up expired tokens
Token::where('expires_at', '<', now())->delete();
use Illuminate\Support\Facades\RateLimiter;
public function generateToken()
{
return RateLimiter::attempt(
'token-gen:'.$this->user->id,
$perMinute = 5,
function () {
$generator = new RandomBytesGenerator(bytes: 32);
return $generator->generate();
}
);
}

Choose Random Bytes when:

  • Maximum cryptographic security needed
  • Generating encryption keys
  • Creating security tokens
  • Building authentication systems
  • Need deterministic output length
  • Working with binary data

Choose other generators for:

  • Random String: Need alphanumeric (more compact)
  • UUID: Need time-ordered or RFC-compliant IDs
  • NanoID: Need URL-safe with custom alphabet
  • Sqids: Need encodeable/decodeable IDs
  • Never use less than 16 bytes for security tokens
  • Use 32 bytes for high-security applications
  • Use 64 bytes for master secrets and encryption keys
// Encrypt tokens at rest
use Illuminate\Support\Facades\Crypt;
$encrypted = Crypt::encryptString($token);
$decrypted = Crypt::decryptString($encrypted);
  • Always use HTTPS for token transmission
  • Never log tokens in plain text
  • Rotate tokens periodically
  • Implement token revocation