Oihana PHP

encoding

Table of Contents

Functions

base64UrlDecode()  : string|false
Decodes a base64url-encoded string (RFC 4648 §5).
base64UrlEncode()  : string
Encodes binary data into a base64url string (RFC 4648 §5).
hexDecode()  : string|false
Decodes a hexadecimal string into raw bytes.
hexEncode()  : string
Encodes binary data into a lowercase hexadecimal string.
randomBase64Url()  : string
Generates a cryptographically secure random token, encoded in base64url (RFC 4648 §5, URL-safe, no padding).
randomHex()  : string
Generates a cryptographically secure random token, encoded as a lowercase hexadecimal string.
randomPassword()  : string
Generates a password nobody chose and nobody has to remember: meant to be copied, not typed from memory.

Functions

base64UrlDecode()

Decodes a base64url-encoded string (RFC 4648 §5).

base64UrlDecode(string $value) : string|false

The decoder is permissive on padding but strict on alphabet:

  • Inputs in canonical URL-safe form (no trailing =) are accepted.
  • Inputs that still carry the standard padding (=, ==) are also accepted, for interoperability with implementations that emit padded base64url.
  • Any character outside [A-Za-z0-9_\-] (or = only as trailing padding) causes the function to return false. This includes +, /, whitespace, newlines, control characters and any non-ASCII byte.

The function is binary-safe: it operates on ASCII bytes regardless of the current mbstring.func_overload setting or locale.

The function does not raise exceptions ; it mirrors the contract of base64_decode() and returns false on any invalid input.

Note: when comparing a decoded value to a known secret (e.g. an HMAC tag), always use a constant-time comparison such as hash_equals() ; this function itself does not perform any cryptographic comparison.

Parameters
$value : string

The base64url string to decode. May be empty.

Tags
example
use function oihana\core\encoding\base64UrlDecode;

echo base64UrlDecode( 'aGVsbG8' ) ;          // "hello"  (no padding)
echo base64UrlDecode( 'aGVsbG8=' ) ;         // "hello"  (with padding, tolerated)
echo base64UrlDecode( '-_8' ) ;              // "\xFB\xFF"

var_dump( base64UrlDecode( 'aGVsbG8+' ) ) ;  // bool(false) — '+' is not URL-safe
var_dump( base64UrlDecode( "aGVs\nbG8" ) ) ; // bool(false) — whitespace forbidden
var_dump( base64UrlDecode( 'aGVsbG8é' ) ) ;  // bool(false) — non-ASCII forbidden
see
base64UrlEncode()

For the inverse operation.

author

Marc Alcaraz (ekameleon)

since
1.0.8
Return values
string|false —

The decoded raw bytes, or false if $value is not a valid base64url string.

base64UrlEncode()

Encodes binary data into a base64url string (RFC 4648 §5).

base64UrlEncode(string $binary) : string

The output uses the URL- and filename-safe alphabet (- and _ instead of + and /) and omits the trailing = padding, producing the canonical URL-safe form used by JWT/JOSE, WebPush, signed URLs, etc.

The function is binary-safe: any byte sequence is accepted, including null bytes and arbitrary UTF-8.

Parameters
$binary : string

Raw bytes to encode. May be empty.

Tags
example
use function oihana\core\encoding\base64UrlEncode;

echo base64UrlEncode( 'hello' ) ;
// Outputs: aGVsbG8

echo base64UrlEncode( "\xFB\xFF" ) ;
// Outputs: -_8 (note the URL-safe '-' and '_', no '=' padding)

// JWT-style usage
$header  = base64UrlEncode( json_encode( [ 'alg' => 'HS256' , 'typ' => 'JWT' ] ) ) ;
$payload = base64UrlEncode( json_encode( [ 'sub' => '42' , 'iat' => time() ] ) ) ;
$signing = $header . '.' . $payload ;
see
base64UrlDecode()

For the inverse operation.

author

Marc Alcaraz (ekameleon)

since
1.0.8
Return values
string —

The base64url-encoded representation, without padding. Always a subset of [A-Za-z0-9_-].

hexDecode()

Decodes a hexadecimal string into raw bytes.

hexDecode(string $value) : string|false

Strict, warning-free counterpart of hex2bin() :

  • Accepts both lowercase and uppercase digits ([0-9a-fA-F]).
  • Requires an even number of characters ; an odd length yields false.
  • Rejects any character outside the hex alphabet (including whitespace and non-ASCII bytes) with false instead of PHP's native warning.
  • The empty string decodes to the empty string.

The function does not raise exceptions ; it returns false on any invalid input, mirroring the contract of base64UrlDecode().

Note: when comparing a decoded value to a known secret (e.g. an HMAC tag), always use hash_equals() for constant-time comparison.

Parameters
$value : string

The hexadecimal string to decode. May be empty.

Tags
example
use function oihana\core\encoding\hexDecode;

echo hexDecode( '616263' ) ;          // "abc"
echo hexDecode( '00FF'   ) ;          // "\x00\xFF" (uppercase accepted)
echo hexDecode( ''       ) ;          // ""

var_dump( hexDecode( '6'      ) ) ;   // bool(false) — odd length
var_dump( hexDecode( '6Z'     ) ) ;   // bool(false) — invalid char
var_dump( hexDecode( '61 62'  ) ) ;   // bool(false) — whitespace forbidden
see
hexEncode()

For the inverse operation.

author

Marc Alcaraz (ekameleon)

since
1.0.8
Return values
string|false —

The decoded raw bytes, or false if $value is not a valid hexadecimal string of even length.

hexEncode()

Encodes binary data into a lowercase hexadecimal string.

hexEncode(string $binary) : string

Thin wrapper around bin2hex() provided for API symmetry with the other helpers of this package (hexDecode(), base64UrlEncode()).

The function is binary-safe and always produces lowercase output, which matches the convention used for hashes, tokens and HMAC tags across the Oihana ecosystem.

Parameters
$binary : string

Raw bytes to encode. May be empty.

Tags
example
use function oihana\core\encoding\hexEncode;

echo hexEncode( 'abc' ) ;        // "616263"
echo hexEncode( "\x00\xFF" ) ;   // "00ff"
echo hexEncode( '' ) ;           // ""
see
hexDecode()

For the inverse operation.

author

Marc Alcaraz (ekameleon)

since
1.0.8
Return values
string —

A string of [0-9a-f] characters, twice as long as $binary.

randomBase64Url()

Generates a cryptographically secure random token, encoded in base64url (RFC 4648 §5, URL-safe, no padding).

randomBase64Url([int $bytes = 32 ]) : string

The function reads $bytes of entropy from random_bytes() (a CSPRNG) and encodes the result with base64UrlEncode(). The output is safe to use in URLs, HTTP headers, filenames, JWT identifiers, OAuth state/nonce, CSRF tokens and similar contexts.

Output length is ceil( $bytes * 4 / 3 ) characters (without padding). Default $bytes = 32 yields 256 bits of entropy → 43 characters, which is the recommended size for cryptographic tokens.

Parameters
$bytes : int = 32

Number of random bytes to generate. Must be >= 1. Defaults to 32 (256 bits of entropy).

Tags
throws
InvalidArgumentException

If $bytes is less than 1.

RandomException

If no source of randomness is available (propagated from random_bytes()).

example
use function oihana\core\encoding\randomBase64Url;

$csrfToken     = randomBase64Url() ;        // 256 bits, 43 chars
$oauthState    = randomBase64Url( 16 ) ;    // 128 bits, 22 chars
$refreshToken  = randomBase64Url( 48 ) ;    // 384 bits, 64 chars

// Always URL-safe and unpadded
preg_match( '/^[A-Za-z0-9_\-]+$/' , $csrfToken ) ; // 1
see
base64UrlEncode()

Encoder used internally.

randomHex()

Hex-encoded variant.

author

Marc Alcaraz (ekameleon)

since
1.0.8
Return values
string —

The base64url-encoded random token. Always a subset of [A-Za-z0-9_-].

randomHex()

Generates a cryptographically secure random token, encoded as a lowercase hexadecimal string.

randomHex([int $bytes = 32 ]) : string

The function reads $bytes of entropy from random_bytes() (a CSPRNG) and encodes the result with bin2hex(). The output is safe to use in URLs, logs, filenames, correlation/request IDs, JWT jti, refresh tokens and similar contexts.

Output length is exactly 2 * $bytes characters. Default $bytes = 32 yields 256 bits of entropy → 64 characters.

For shorter URL-friendly tokens at equivalent entropy, prefer randomBase64Url().

Parameters
$bytes : int = 32

Number of random bytes to generate. Must be >= 1. Defaults to 32 (256 bits of entropy).

Tags
throws
InvalidArgumentException

If $bytes is less than 1.

RandomException

If no source of randomness is available (propagated from random_bytes()).

example
use function oihana\core\encoding\randomHex;

$requestId     = randomHex( 8  ) ; // 16 hex chars  ( 64 bits)
$correlationId = randomHex( 16 ) ; // 32 hex chars  (128 bits)
$refreshToken  = randomHex()      ; // 64 hex chars (256 bits, default)

// Always lowercase hex
preg_match( '/^[0-9a-f]+$/' , $refreshToken ) ; // 1
see
hexEncode()

Encoder used internally.

randomBase64Url()

Base64url variant (shorter at equivalent entropy).

author

Marc Alcaraz (ekameleon)

since
1.0.8
Return values
string —

Lowercase hexadecimal string of length 2 * $bytes.

randomPassword()

Generates a password nobody chose and nobody has to remember: meant to be copied, not typed from memory.

randomPassword([int $length = 28 ]) : string

The alphabet

Letters and digits only, minus the five that are misread when a password is copied from a screen or a notebook: l, I, 1, O, 0. That leaves 57 characters. No punctuation, so the value travels through a shell argument, a TOML or INI string, a URL or a command-line tool without anything having to escape it.

The length

28 characters out of 57 is about 163 bits. The length is what carries the strength here, and it costs nothing for a password that is copied. A length under 16 is raised to 16, silently: the function answers with a usable password rather than an error, unlike randomHex(), which throws on a length it cannot honour.

Each character is drawn with random_int(), a CSPRNG — never rand() or shuffle(), which are predictable from a few samples.

Parameters
$length : int = 28

How many characters, 16 at least.

Tags
throws
RandomException

If the system has no source of randomness.

example
use function oihana\core\encoding\randomPassword;

randomPassword() ;     // e.g. 'pKx7DwqT4hLvZrc9Ym3nEuB8fGsa' (28 characters)
randomPassword( 40 ) ; // 40 characters
randomPassword( 4 ) ;  // 16 characters: the floor
see
randomHex()

A token of hexadecimal characters.

randomBase64Url()

A shorter token at equivalent entropy, with - and _.

author

Marc Alcaraz (ekameleon)

since
1.4.0
Return values
string —

The password: max( 16 , $length ) characters of [a-km-zA-HJ-NP-Z2-9].

On this page

Search results