Base64 atob / btoaLoading saved progress…

Base64 atob / btoa

Base64 encodes binary data as text by packing every 3 bytes into 4 characters from a fixed 64-symbol alphabet, so raw bytes can travel through text-only channels like URLs, JSON, and email. In the browser, btoa does the encoding and atob does the decoding. You will implement both from scratch — the bit-packing, the alphabet lookup, and the padding — without calling the built-in btoa / atob or Node's Buffer.

btoa works on a binary string: a string where each character's code is a single byte from 0 to 255. atob takes base64 text and returns that binary string back.

Signature

btoa(binaryString)  // -> base64 string
atob(base64String)  // -> binary string (each char code 0-255)

Both live on one object: atobBtoa = { btoa, atob }.

Examples

atobBtoa.btoa('Man');           // 'TWFu'   (3 bytes -> 4 chars, no padding)
atobBtoa.btoa('Ma');            // 'TWE='   (2 bytes -> 3 chars + one '=')
atobBtoa.btoa('M');             // 'TQ=='   (1 byte  -> 2 chars + two '=')
atobBtoa.btoa('Hello, World!'); // 'SGVsbG8sIFdvcmxkIQ=='

atobBtoa.atob('TWFu');          // 'Man'
atobBtoa.atob('TQ==');          // 'M'
atobBtoa.atob(atobBtoa.btoa('any Latin-1 string')); // round-trips to the input

Notes

  • Work 3 bytes at a time — three 8-bit bytes hold 24 bits, which split evenly into four 6-bit base64 characters. That 3-to-4 ratio is the core of the algorithm.
  • Alphabet — index 0 to 63 maps to A-Z, then a-z, then 0-9, then + and /.
  • Padding — when the input length is not a multiple of 3, pad the output with = so its length stays a multiple of 4: one = for a 2-byte tail, two for a 1-byte tail.
  • Guard bytes above 255btoa handles only single bytes (Latin-1). If a character's code is above 255, throw, exactly as the real btoa does.
  • Round-tripatob(btoa(s)) must return s for every Latin-1 string s, including lengths that need 1 or 2 pad characters.
  • Do not use the built-ins — no global btoa / atob, no Buffer. String.fromCharCode and charCodeAt are allowed as byte primitives.

FAQ

Why does btoa throw on characters with a code above 255?
Base64 encodes bytes, and a byte only holds 0-255. btoa reads each character as one byte, so a character like an emoji or an accented letter whose code is above 255 has no single-byte form and btoa throws. Encode the text as UTF-8 bytes first (for example with TextEncoder) when you need Unicode.
What are the = characters at the end for?
They pad the output so its length is always a multiple of 4. Base64 packs 3 bytes into 4 characters, so when the input length is not a multiple of 3 the encoder adds one = for a 2-byte tail and two = for a 1-byte tail, which tells the decoder how many bytes to recover.
Is base64 a form of encryption?
No. Base64 is a reversible encoding with a fixed, public alphabet, so anyone can decode it with atob. It hides nothing. Use it to carry binary data through text-only channels, never to protect a secret.
Loading editor…