Hex vs base64url encoding for 192-bit random tokens
A same-entropy comparison of hexadecimal and unpadded base64url token representation.
The correctness boundary
For 24 cryptographically random bytes, how do hex and base64url compare in encoding time and string length?
Token strength comes from unpredictable random bytes, not from the visible encoding. Encoding affects length, transport compatibility and operator ergonomics.
This experiment uses random_bytes in both variants so entropy remains identical.
Base64url should produce a shorter token, while hex offers simpler visual inspection and broad character-set compatibility.
Measured evidence
What this run shows: Hex token encoded the same random bytes sooner, while alphabet, padding and fixed-length interface requirements decide the usable representation. The slowest-to-fastest median spread was 18.43% on the measured host.
| Variant | Median | Middle 50% | Operations/s | Additional measure |
|---|---|---|---|---|
| Hex tokenFastest | 539.95 ns | 523.74 ns–564.34 ns | 1,852,017 | 48 output bytes |
| Base64url token | 639.45 ns | 635.92 ns–667.93 ns | 1,563,853 | 32 output bytes |
What could go wrong with a timing-only choice?
Do not equate a longer visible token with more entropy when both encode the same bytes. Hex uses two characters per byte; base64url packs the same information more densely.
Choose the representation that matches storage, URL and human-handling requirements. Keep the underlying byte count tied to the threat model.
Implementation checks
- Use random_bytes or an equivalent cryptographically secure generator.
- Use base64url for compact URL-safe tokens and hex where simplicity is more important than length.
- Store only a hash of bearer tokens when the application can verify by lookup.
How this boundary was tested
- Each operation generates 24 fresh random bytes.
- One variant uses bin2hex. The other uses standard Base64 followed by URL-safe alphabet replacement and padding removal.
- The resulting string length is consumed and published.
Open measured environment
- Measurement run
- 2026-07-22T15:23:56+00:00
- PHP
- 8.4.23 (cli)
- Operating system
- Linux 4.18.0-553.85.1.el8_10.x86_64
- Architecture
- x86_64
- Processor
- AMD EPYC-Rome Processor
- Reported host memory
- 15.02 GiB host total
- CLI OPcache
- 0
- PHP memory limit
- 1024M
- Loaded study extensions
- json, openssl, zlib, mbstring, pdo_sqlite
- Timing clock
- hrtime(true)
- Measured rounds
- 7
Scope and unresolved questions
- Entropy-source latency can vary by host and dominate encoding cost.
- The study does not estimate attack resistance for a specific application.
Primary documentation
Use these documents to verify the required API, encoding or filesystem behavior. ASAMB supplies the local measurements, not the normative rule.
Inspect or rerun the evidence
The common runner and study-specific fixture are public so the result can be challenged on another PHP host.