Base64 Encoder & Decoder
Encode text or any file to Base64, or decode Base64 back to text or a downloadable file. Standard and URL-safe alphabets, optional ‘=’ padding, UTF-8 round-trip verified. Runs entirely in your browser.
How it works
Base64 is the standard way to carry arbitrary bytes through a text-only channel. The encoder takes three input bytes (24 bits) and slices them into four 6-bit groups; each group indexes a 64-character alphabet. When the input is not a multiple of 3 bytes, the last group is partial and one or two padding = characters fill it out — that's why standard Base64 strings always have a length that is a multiple of 4. The encoder on this page implements both alphabets defined by RFC 4648: §4 standard (ending in +/) and §5 URL-safe (ending in -_), with optional padding for the URL-safe form as §3.2 allows.
- Bytes from text. When you paste text, it is first converted to UTF-8 bytes by the standard
TextEncoder. Sinhala, Tamil, emoji and any other Unicode survive the round-trip — the alternative (UTF-16 directly to Base64) would corrupt anything outside the BMP. - 3-byte → 4-char chunking. For each group of 3 input bytes, the encoder packs them into a 24-bit value
v = (a << 16) | (b << 8) | cand emits four characters by shifting and masking 6 bits at a time:alpha[(v >> 18) & 63]thenalpha[(v >> 12) & 63]and so on. The same code path handles both alphabets — only the 64-character lookup table changes. - Tail and padding. If the last group has 1 or 2 bytes, the encoder shifts the missing positions to zero, emits 2 or 3 data characters, then appends two or one
=characters when padding is on. URL-safe outputs default to no padding (the JWT / OAuth PKCE convention). - Decoder = the inverse. Whitespace and trailing
=are stripped, then a single 256-entry lookup translates each character to its 6-bit value (the table accepts both alphabets simultaneously, so you don't have to pick a variant). Every 4 input characters produce 3 output bytes, with the tail logic mirrored. A finalTextDecoder("utf-8", { fatal: true })tries to read the bytes as text — if that fails, the page hands them to a download button instead.
Two independent invariants are checked on every page load to keep the implementation honest. First, the encoded length is computed by a separate formula 4 × ceil(bytes / 3) (with padding) and asserted against the actual encoder output. Second, a probe string containing ASCII punctuation, Sinhala (ශ්රී ලංකා), and an emoji is round-tripped encode → decode for both alphabets, and the result must match the original. Both checks are surfaced as the green “Verified · round-trip” badge in the calculator header. If you ever see the badge flip to red on a real input, please email me — that is a real regression.
Worked examples
Frequently asked questions
Sources & references
- IETF RFC 4648 — The Base16, Base32, and Base64 Data Encodings
- WHATWG Encoding Standard — TextEncoder / TextDecoder (UTF-8)
- WHATWG HTML §8.4 — btoa / atob reference
- RFC 7515 (JSON Web Signature) Appendix C — base64url encoding
- RFC 7636 (OAuth PKCE) — base64url-encoded code verifier / challenge
- MDN Web Docs — Base64 glossary entry
The encoder, decoder, and length predictor on this page were last cross-checked against RFC 4648 reference vectors and the browser's built-in btoa / atob on 2026-05-11. Any algorithmic change bumps that date. If you spot a mismatch with another implementation, email me below.
Related tools
Comments & feedback
Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.
Spotted a decoding edge case, an alphabet mismatch, or want to suggest a new feature?
Email me at [email protected] — most fixes ship within 24 hours.