Skip to content

Base64 encoding with ard/base64

The ard/base64 module provides base64 encoding and decoding in two variants: standard (+// alphabet) and URL-safe base64url (-/_ alphabet). Both variants accept an optional no_pad flag to strip = padding when required.

Base64 is a reversible text encoding (not a cryptographic primitive). It is commonly used to embed binary data in text-only contexts like JSON payloads, URLs, JWTs, and HTTP headers.

The base64 module provides:

  • Standard base64 with encode and decode
  • URL-safe base64 with encode_url and decode_url
  • Both variants support an optional no_pad flag to strip = padding
use ard/base64
use ard/io
fn main() {
let encoded = base64::encode("hello")
io::print(encoded) // "aGVsbG8="
match base64::decode(encoded) {
ok(original) => io::print(original),
err(msg) => io::print("decode failed: {msg}"),
}
}
VariantAlphabetUse for
encode / decodeA–Z a–z 0–9 + /Email, generic binary-to-text
encode_url / decode_urlA–Z a–z 0–9 - _URLs, JWTs, PKCE, filenames

Both variants pad with = by default. Pass no_pad: true to strip padding — this is required by:

  • JWT (JSON Web Tokens) — header and payload segments use encode_url(..., true)
  • PKCE (OAuth 2.1) — base64url(sha256(verifier)) must have no = padding

Encode input using standard base64 (alphabet A–Z, a–z, 0–9, +, /).

The optional no_pad flag controls trailing = padding:

  • Omitted or none: padded (default)
  • true: no padding
// With padding (default)
base64::encode("hello") // "aGVsbG8="
base64::encode("f") // "Zg=="
base64::encode("fo") // "Zm8="
base64::encode("foo") // "Zm9v"
base64::encode("") // ""
// Without padding
base64::encode("f", true) // "Zg"
base64::encode("fo", true) // "Zm8"

fn decode(input: Str, no_pad: Bool?) Str!Str

Section titled “fn decode(input: Str, no_pad: Bool?) Str!Str”

Decode a standard base64 string. The no_pad flag must match how the input was encoded. Returns ok(decoded) or err(message) if the input is not valid base64.

// Padded input (default)
let decoded = try base64::decode("aGVsbG8=") -> _ { "" }
// decoded == "hello"
// No-padding input
let decoded = try base64::decode("aGVsbG8", true) -> _ { "" }
base64::decode("not!valid!").is_err() // true

fn encode_url(input: Str, no_pad: Bool?) Str

Section titled “fn encode_url(input: Str, no_pad: Bool?) Str”

Encode input using base64url (URL-safe alphabet: A–Z, a–z, 0–9, -, _).

The optional no_pad flag controls trailing = padding:

  • Omitted or none: padded (default)
  • true: no padding — required by JWT and PKCE
// With padding (default)
base64::encode_url("subjects?") // "c3ViamVjdHM_"
base64::encode_url("f") // "Zg=="
// Without padding (JWT, PKCE)
base64::encode_url("f", true) // "Zg"
base64::encode_url("fo", true) // "Zm8"

fn decode_url(input: Str, no_pad: Bool?) Str!Str

Section titled “fn decode_url(input: Str, no_pad: Bool?) Str!Str”

Decode a base64url-encoded string. The no_pad flag must match how the input was encoded:

  • Omitted or none: expect = padding
  • true: expect input without padding
// Padded input
let decoded = try base64::decode_url("aGVsbG8gd29ybGQ=") -> _ { "" }
// No-padding input (JWT, PKCE)
let decoded = try base64::decode_url("aGVsbG8gd29ybGQ", true) -> _ { "" }
use ard/base64
use ard/io
fn main() {
let original = "The quick brown fox jumps over the lazy dog"
let encoded = base64::encode(original)
io::print(encoded)
let decoded = try base64::decode(encoded) -> err {
io::print("decode failed: {err}")
return
}
io::print(decoded)
}
use ard/base64
use ard/crypto
fn pkce_challenge(verifier: Str) Str {
let hashed = crypto::sha256(verifier)
base64::encode_url(hashed, true) // no padding for PKCE
}
use ard/base64
use ard/json
fn encode_segment(payload: Dynamic) Str!Str {
let raw = try json::encode(payload)
Result::ok(base64::encode_url(raw, true)) // no padding for JWT
}

Decode functions return a Result, so bad input is surfaced as an error rather than a panic:

use ard/base64
fn safe_decode(input: Str) Str {
base64::decode(input).or("<invalid>")
}