NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Four static codecs, each with encode() and decode(). Encoding is total; decoding is deliberately strict and throws Codec\InvalidEncodingException on malformed or non-canonical input, so a tampered value never silently decodes into different bytes:

use RoundlyConsulting\Crypto\Facades\Crypto;

$encoded = Crypto::base64UrlEncode($bytes);      // unpadded, URL-safe
$bytes   = Crypto::base64UrlDecode($encoded);    // STRICT — throws InvalidEncodingException

Crypto::base64Encode($bytes);   Crypto::base64Decode($padded);
Crypto::base32Encode($bytes);   Crypto::base32Decode($secret);
Crypto::hexEncode($bytes);      Crypto::hexDecode($hex);

Or call the classes the facade fronts directly:

use RoundlyConsulting\Crypto\Codec\Base64Url;
use RoundlyConsulting\Crypto\Codec\Base64;
use RoundlyConsulting\Crypto\Codec\Base32;
use RoundlyConsulting\Crypto\Codec\Hex;

$encoded = Base64Url::encode($bytes);        // unpadded, URL-safe
$bytes   = Base64Url::decode($encoded);      // STRICT: rejects +, /, =, and non-alphabet

$padded  = Base64::encode($bytes);           // standard padded base64 (+/ alphabet, = padding)
$bytes   = Base64::decode($padded);          // STRICT: rejects non-canonical / non-alphabet

$secret  = Base32::encode($randomBytes);     // e.g. "GEZDGNBVGY3TQOJQ"
$bytes   = Base32::decode($secret);          // case-insensitive; canonical, strict

$hex     = Hex::encode($bytes);              // lower-case, e.g. "68656c6c6f"
$bytes   = Hex::decode($hex);                // throws on odd length or any non-hex character
ClassFormDecoding rejects
Base64UrlUnpadded URL-safe alphabet (RFC 4648 §5).+, /, =, any non-alphabet byte, empty input and a dangling single character.
Base64Standard alphabet with = padding (RFC 4648 §4).Non-alphabet bytes, wrong or missing padding, whitespace and non-canonical encodings.
Base32A–Z2–7, unpadded on encode (RFC 4648).Case-insensitive, but rejects non-alphabet characters (including whitespace), interior =, dangling characters and non-zero trailing bits.
HexLower-case hexadecimal.Odd length and any non-hex character.

Handling bad input

use RoundlyConsulting\Crypto\Codec\InvalidEncodingException;

try {
    $bytes = Base64Url::decode($userInput);
} catch (InvalidEncodingException $e) {
    // reject the tampered / malformed value
}

Base32 does not strip whitespace — trim input first if a source adds newlines. Base32::ALPHABET is exposed as a public constant, and every codec is also reachable through the Crypto facade.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.