webtrajans
en

Base64 and URL encoding: what they are and when to use them

Base64 turns binary data into plain text; URL encoding makes text safe to put in a web address. Neither hides anything. Here is how both work, with worked examples and pitfalls.

Updated: 5 min read

Base64 and URL encoding solve the same basic problem: some channels only accept a limited set of characters. Email was designed for text, URLs reserve characters like ?, & and #, and JSON can’t hold raw binary bytes. Encoding converts data into a safe alphabet and back again, losslessly. Developers meet both every day, in API tokens, data URLs, email attachments and query strings, and mixing them up causes confusing bugs. Use our Base64 encoder/decoder and URL encoder to try the examples below.

Base64: how it works

Base64 (defined in RFC 4648) represents binary data using 64 printable characters:

A–Z  a–z  0–9  +  /     (and = for padding)

The algorithm:

  1. Take the input 3 bytes (24 bits) at a time.
  2. Split the 24 bits into four 6-bit groups.
  3. Map each 6-bit value (0–63) to a character in the alphabet.
  4. If the input isn’t a multiple of 3 bytes, pad the output with =.

Worked example: “Man”

M a n
ASCII 77 97 110
Binary 01001101 01100001 01101110

Regrouped into 6 bits: 010011 010110 000101 101110 → 19, 22, 5, 46 → TWFu.

More examples:

Input Base64
Man TWFu
Hi! SGkh
Hi SGk=
café (UTF-8) Y2Fmw6k=

Note that é is two bytes in UTF-8, so the text must be converted to bytes (normally UTF-8) before encoding. In JavaScript, btoa("café") fails or gives wrong results with non-Latin characters; encode to UTF-8 first with TextEncoder.

Size overhead

Output is 4/3 the size of the input: about 33% larger. A 3 MB image becomes about 4 MB of Base64 text. MIME email also inserts line breaks every 76 characters, adding a little more. That’s why attachments use more of your mailbox’s size limit than the file size suggests.

Where Base64 is used

  • Email attachments (MIME) and images embedded in HTML emails.
  • Data URLs: embedding small files directly in HTML or CSS:
<img src="data:image/png;base64,iVBORw0KGgo..." alt="icon">
  • HTTP Basic authentication: Authorization: Basic dXNlcjpwYXNz is just user:pass encoded. It is protected only by HTTPS.
  • JSON Web Tokens (JWT) and other tokens, using the URL-safe variant.
  • Storing binary data (keys, certificates, small files) in JSON, XML or environment variables. PEM certificates are Base64 between -----BEGIN and -----END lines.

When not to use data URLs

Inlining images saves an HTTP request but adds 33% to the size, can’t be cached separately and bloats your HTML or CSS. Use it only for very small assets (a few KB, such as tiny icons). For everything else, serve normal image files; see our image optimisation guide.

Base64URL

Standard Base64 uses + and /, which have special meaning in URLs and file names. Base64URL (also RFC 4648) replaces them:

Standard Base64URL
+ -
/ _
= padding Often omitted

JWTs, many API tokens and some file-naming schemes use Base64URL. Decoding a Base64URL string with a standard decoder may fail until you swap the characters back and restore the padding.

URL encoding (percent-encoding)

URLs can only contain a limited set of ASCII characters, and some characters are reserved for structure (RFC 3986):

: / ? # [ ] @ ! $ & ' ( ) * + , ; =

Percent-encoding replaces any unsafe or reserved character with % followed by its byte value in hexadecimal. Non-ASCII characters are first converted to UTF-8 bytes, each of which is encoded.

Character Encoded
Space %20 (or + in form data)
& %26
= %3D
? %3F
/ %2F
# %23
£ %C2%A3
é %C3%A9

Unreserved characters never need encoding: A–Z a–z 0–9 - _ . ~.

Example

A search query fish & chips / £5 placed in a query parameter:

https://example.com/search?q=fish%20%26%20chips%20%2F%20%C2%A35

Without encoding, & would start a new parameter and the query would be cut off at “fish “.

In code

encodeURIComponent("fish & chips / £5");
// "fish%20%26%20chips%20%2F%20%C2%A35"

const url = new URL("https://example.com/search");
url.searchParams.set("q", "fish & chips / £5"); // encodes for you (spaces as +)
from urllib.parse import quote, urlencode
quote("fish & chips / £5", safe="")
urlencode({"q": "fish & chips / £5"})

Common mistakes

  • Treating encoding as security. Base64-encoded passwords in config files or URLs are effectively plain text. For passwords, use proper hashing; see our strong password guide.
  • Double encoding. Encoding an already-encoded string turns %20 into %2520. Encode once, at the point where you build the URL.
  • Using encodeURI for parameter values. It leaves & and = unencoded and breaks the query.
  • Forgetting UTF-8. Encode text to UTF-8 bytes before Base64 or percent-encoding.
  • Mixing Base64 and Base64URL when decoding tokens.
  • Putting sensitive data in URLs. URLs are logged by servers, proxies and browser history, even over HTTPS.

Checklist

  • Base64 for binary-to-text (attachments, tokens, small embeds); expect +33% size.
  • Base64URL for anything that goes in a URL or file name.
  • Percent-encode each query parameter value with a proper function.
  • Encode exactly once and use UTF-8.
  • Never rely on encoding to hide information.

Frequently asked questions

Is Base64 encryption?

No. Base64 is a reversible encoding with no key; anyone can decode it instantly. Never use it to protect passwords, API keys or personal data. Use proper encryption or hashing instead.

Why does Base64 make files bigger?

Every 3 bytes of input become 4 characters of output, so Base64 data is about 33% larger than the original, plus padding and any line breaks.

What is the difference between encodeURI and encodeURIComponent?

encodeURI encodes a full URL and leaves characters such as / ? & = # intact. encodeURIComponent encodes everything except letters, digits and - _ . ! ~ * ' ( ), so it is the right choice for a single query parameter value.

Should spaces be %20 or + in a URL?

In the path, a space must be %20. In query strings submitted by HTML forms (application/x-www-form-urlencoded), + also means a space. %20 works in both places, so it is the safer choice.

Related guides