Auth broke at midnight: tokens generated with + and / sailed through tests, then shattered in production URLs — plus became space, slash split the path, padding got stripped by a proxy. The fix was three characters of alphabet swap: URL-safe Base64. Standard vs URL-safe is the most common encoding bug I review, and it hides until deployment. This guide maps both alphabets, padding rules, size math and the JWT connection.
Part of the developer toolkit guide. Encode in the Base64 tool (mode toggle); inspect tokens in the JWT decoder.
Two alphabets: +/= vs -_ (no pad)
| Standard (RFC 4648) | URL-safe | |
|---|---|---|
| Chars 62–63 | + / | - _ |
| Padding | = required | Omitted |
| Safe in URLs | No (space/path splits) | Yes |
| Safe in email/MIME | Yes (76-char wrap) | Decoders may choke |
Example (fa fb fc) | +vv8 | -vv8 |
Rule: standard for MIME, email and data-URLs; URL-safe for tokens, query params, filenames and slugs. Mixing modes (URL-safe encode, standard decode) is the midnight-outage pattern — standardize per boundary and document which side owns encoding.
Size math: 33% overhead, UTF-8 first
Base64 inflates ~33%: every 3 bytes become 4 characters. Budget it: a 3MB binary becomes 4MB of text — fine for tokens, fatal for “embed the video in JSON” designs. UTF-8 encodes first: café → bytes 63 61 66 C3 A9 → Y2Fmw6k=; emoji cost 4 bytes each, so “🎉” alone becomes 8 characters. Forgetting the UTF-8 step produces mojibake that decodes “successfully” into garbage — always encode text as UTF-8 bytes, decode bytes as UTF-8 text. The 76-character mail wrap is transport-only; strip whitespace before decoding stored values.
JWT segments are Base64URL (and why padding vanishes)
Every JWT is three Base64URL segments joined by dots — header, payload, signature. No padding, -_ alphabet, always. So exp: 1717252800 rides inside segment two, and decoding it needs a URL-safe decoder (standard decoders reject unpadded input or misread -_). Workflow: decode segments in the Base64 tool with URL-safe mode, then hand the full token to the JWT decoder for claim inspection — and remember decoding ≠ verifying (see expiry checks).
General guidance only. Base64 is encoding, not encryption — anyone can decode it. Never put secrets in tokens or URLs.