What Does %20 Mean in a URL? Percent-Encoding Explained Simply
%20 in a URL means a space. URLs can't contain raw spaces, so browsers and servers replace each space with a percent sign followed by 20, the hexadecimal code for the space character.
Base64 encoding turns any sequence of bytes into a safe string of ASCII characters using a 64-symbol alphabet, with = used as padding when the input length is not a multiple of three.
Base64 encoding turns any sequence of bytes into a safe string of ASCII characters using a 64-symbol alphabet, with = used as padding when the input length is not a multiple of three. It is a transfer encoding, not encryption: anyone can decode it. Developers use it for data URLs, HTTP Basic Authentication headers, email attachments (MIME) and embedding small binary blobs in JSON or XML. It is the wrong tool when you need secrecy, password hashing or compression.
The name comes from the radix: sixty-four symbols. That set is large enough to encode six bits per character and small enough to stay inside portable ASCII. URL-safe and filename-safe variants exist for places where + and / are awkward.
This guide explains the alphabet from RFC 4648, how padding works, when Base64 helps, when it hurts, and short encode and decode examples. You can try any string in the free Base64 encoder and decoder on mfaysal.com. For a concise glossary entry, see MDN's Base64 page.
Contents
Computers store everything as bytes. Some channels only accept printable ASCII: older email systems, certain HTTP headers, or text-only config files. If you paste raw binary into those places, bytes get corrupted or rejected. Base64 solves that by rewriting every group of three bytes as four characters chosen from a fixed alphabet.
Each Base64 character represents 6 bits. Three bytes are 24 bits, which splits cleanly into four 6-bit values. The encoder maps each 6-bit value to one character. The result is about 33% larger than the original, because four characters (32 bits of text) carry only 24 bits of data. That size trade-off is the price of ASCII safety.
Decoding reverses the map: four characters become three bytes. Invalid characters outside the alphabet usually cause a decoder error. Whitespace rules vary by decoder, so strip spaces and newlines before you decode if your source wraps lines.
Think of Base64 as a translation layer. The meaning of the bytes does not change; only the written form does. A PNG file that is Base64-encoded is still a PNG after decoding. That is why you can round-trip data safely: encode, ship through a text channel, decode, and get identical bytes back, provided nobody truncates the string or changes the alphabet.
Line wrapping is another historical detail. Older MIME rules often wrapped Base64 at 76 characters per line. Modern APIs usually prefer a single unbroken string. If a decoder fails on what looks like valid Base64, check for line breaks, spaces or a missing padding character before you assume the data is corrupt.
Historically, Base64 grew out of the need to move binary through systems designed for English text. MIME standardised it for email; HTTP and HTML later adopted the same idea for headers and data URLs. The core algorithm has stayed stable for decades, which is why a string encoded in the 1990s still decodes correctly today.
RFC 4648 defines the standard alphabet used almost everywhere on the web:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/That is 26 uppercase letters, 26 lowercase letters, 10 digits, plus and slash. The equals sign (=) is not part of the alphabet; it is padding. When the input length modulo 3 is 1, the encoder appends two = characters. When it is 2, it appends one =. When it is 0, there is no padding.
| Input length mod 3 | Output padding | Example input | Base64 |
|---|---|---|---|
| 0 | none | Man | TWFu |
| 2 | = | Ma | TWE= |
| 1 | == | M | TQ== |
| 2 | = | Hello | SGVsbG8= |
| 0 | none | Hello! | SGVsbG8h |
Some systems use Base64url instead: - and _ replace + and /, and padding is often omitted. JWT tokens and some URLs need that variant so the string survives query parameters. The formal definitions live in RFC 4648.
Values 0 to 25 map to A–Z, 26 to 51 to a–z, 52 to 61 to 0–9, 62 to +, and 63 to /. Decoders that accept Base64url map 62 to - and 63 to _. Mixing the two alphabets in one string is a common source of bugs, especially when you copy a token from a JWT into a standard decoder.
Padding exists so every encoded block is four characters long. Some streams omit padding and rely on the total length to know where the data ends. If you write a decoder, decide whether you require padding or compute it from the length. Interoperability problems show up most often at API boundaries.
Here are small, checked examples you can reproduce in any language that ships a Base64 library. In Python:
import base64
print(base64.b64encode(b"Hello").decode()) # SGVsbG8=
print(base64.b64decode("SGVsbG8=").decode()) # Hello
print(base64.b64encode(b"user:pass").decode()) # dXNlcjpwYXNzIn the browser, btoa and atob work on Latin-1 strings. For Unicode text, encode to UTF-8 bytes first, then Base64 those bytes. A common pattern is btoa(String.fromCharCode(...new TextEncoder().encode(text))), or use a small helper library.
If you only need to convert a password prompt or a short snippet without opening a terminal, paste it into the Base64 encoder and decoder tool and switch between encode and decode modes.
In JavaScript on Node.js you can use Buffer:
Buffer.from("Hello").toString("base64") // SGVsbG8=
Buffer.from("SGVsbG8=", "base64").toString() // HelloIn PHP, base64_encode and base64_decode do the same job. Always check the decode return value; PHP can return false on failure depending on flags. In shell scripts, base64 on Linux and base64 -d (or base64 --decode) reverse the operation. macOS base64 uses -D for decode in older versions, so check man base64 on your machine.
These tiny examples use the word "Hello" on purpose. Once you trust the round trip on a known string, move on to binary files by reading bytes rather than text.
Three everyday cases show why Base64 exists.
A data URL embeds a file inside HTML or CSS, for example a tiny favicon or a placeholder image:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...The browser decodes the Base64 after the comma and treats the bytes as a PNG. This avoids an extra HTTP request for very small assets. It is a poor choice for large photos, because the HTML grows by about a third and cannot be cached separately.
Basic Auth sends Authorization: Basic followed by Base64 of username:password. For example, aladdin:opensesame becomes YWxhZGRpbjpvcGVuc2VzYW1l. Anyone who sees the header can decode it, so Basic Auth must travel over HTTPS. Base64 here only keeps the header printable; it does not hide the password.
SMTP historically expected 7-bit text. MIME encodes binary attachments as Base64 (or quoted-printable for mostly-text). Your mail client encodes on send and decodes on receive. You rarely type Base64 by hand for email, but you will see it if you view raw message source.
Other valid uses include embedding certificates in PEM files (which wrap Base64 between BEGIN/END lines), storing small binary fields in JSON APIs, and shipping icons inside CSS.
PEM certificates and private keys also use Base64 between header lines such as -----BEGIN CERTIFICATE-----. Tools like OpenSSL emit that format so humans can copy keys through email or chat. The Base64 body is still sensitive: a private key in PEM form is secret material, even though it is "just text".
JSON APIs sometimes include a content_base64 field for small files. That pattern is fine for icons, short audio clips or test fixtures. For multi-megabyte uploads, prefer multipart forms or direct-to-storage uploads so you do not inflate memory on both client and server.
People often confuse encoding with security. Base64 is reversible with no key. Treat encoded data as public as plaintext.
If your goal is to hide a string from casual glance in a log file, Base64 only slows the curious for a second. It does not meet any real threat model.
Another misuse is obfuscation in client-side JavaScript. Shipping an API key as Base64 inside frontend code does not protect it; the browser must decode it to use it, and so can anyone viewing the source. Keep secrets on the server. Our site's own AI image generator follows that rule by calling the model through a server-side API.
Also avoid chaining Base64 repeatedly ("double encoding") unless a protocol explicitly requires it. Each pass adds size and confusion, and it still is not encryption.
Hex (Base16) uses 0-9 and a-f, so each byte becomes two characters: a 50% size increase versus ~33% for Base64. Hex is easier to read by eye and common in hashes and colour codes. URL encoding (percent-encoding) escapes only unsafe characters as %HH; it is for URLs, not for arbitrary binary blobs. Choose Base64 when you need a compact ASCII form of arbitrary bytes. Choose hex for debugging. Choose percent-encoding for query strings.
| Scheme | Alphabet size | Typical expansion | Best for |
|---|---|---|---|
| Base64 | 64 | ~33% | Binary in text channels |
| Hex | 16 | 100% | Debug dumps, digests |
| Percent-encoding | varies | depends | URLs and form fields |
Checksums and hashes almost always appear in hex because developers compare them visually and many tools default to hex digests. Wire protocols that need density prefer Base64. Forms in browsers apply percent-encoding automatically when you submit application/x-www-form-urlencoded data.
If you are unsure which you are looking at, length is a clue: hex doubles the byte count exactly; Base64 uses four characters per three bytes; percent-encoding only expands reserved characters.
If you edit images before embedding them as data URLs, resize and compress first with tools such as the image resizer so the Base64 string stays small.
Test with empty input and with lengths of 1, 2 and 3 bytes so padding paths run. Test Unicode. Test a binary file whose MD5 you know before and after a round trip. Those checks catch the majority of encoding bugs before they reach production.
Finally, document which alphabet you use in API docs. Writing "Base64" alone is ambiguous once Base64url enters the picture. A single sentence such as "standard Base64 with padding" or "Base64url without padding" saves hours of support time.
It rewrites binary data as a string made from 64 ASCII characters so the data can travel through text-only channels without corruption. The original bytes come back unchanged when you decode.
No. Base64 is encoding. Anyone can decode it without a password or key. Use real encryption when you need secrecy, and never treat Base64 as a security control.
Padding fills the last block when the byte length is not a multiple of three. One = means the final group had two input bytes; two = means it had one input byte.
About one third larger. Every three bytes become four characters, so a 300-byte file becomes a 400-character string.
Base64url uses - and _ instead of + and /, and often drops padding. It is safer inside URLs and tokens such as JWTs where + and / would need escaping.
No. Encoding a password does not protect it. Store passwords with a dedicated password hash such as Argon2 or bcrypt, and send them only over HTTPS.
Convert the text to UTF-8 bytes first, then Base64-encode those bytes. Decoding must reverse the same steps or you will get mojibake.
Use a trusted local or site tool such as the free Base64 encoder and decoder on mfaysal.com, and avoid pasting secrets into random third-party sites.
Last checked: 18 October 2026. Specs and docs can change, so confirm anything important with the official source linked above.