URL Encoding vs HTML Encoding vs Base64

Percent-encoding, HTML character references and Base64 all replace characters that would otherwise break something, but each one guards a different container: a URL, a markup document, and a channel that carries only text.

é
233
C3 A9

hex

Type any text to see the bytes behind it. Those bytes are what percent-encoding writes as triplets and what Base64 reads three at a time.

What is the difference between URL encoding, HTML encoding and Base64?

They answer the same shape of question in three different places. Percent-encoding makes a byte safe inside a URL, an HTML character reference makes a character safe inside markup, and Base64 makes arbitrary bytes safe inside a channel that will only carry text.

What each of the three protects, and what it writes instead.
SchemeWhat it protectsDefining specAlphabet or reserved setExample
Percent-encoding A URL, so a delimiter is never mistaken for data RFC 3986 Everything outside the unreserved set may be escaped A space arrives as %20
HTML character reference A markup document, so text is never mistaken for a tag HTML Standard, WHATWG Named references, plus numeric ones for any code point An ampersand arrives as &
Base64 Bytes crossing a channel that accepts only US-ASCII text RFC 4648 Sixty-four characters, with the equals sign kept for padding A space arrives as IA==

The container decides, not the character. The same ampersand is ordinary text in a plain file, a delimiter in a query string and the opening of a reference in markup, and it needs a different treatment in each. That is why the three are not interchangeable: swapping one for another protects the wrong thing.

Each of the three has a converter of its own: head back to the text encoding converter once you know which one you need.

Percent-encoding, in full

A percent-encoded octet is a triplet: a percent sign followed by the two hexadecimal digits of that byte's value.

The unreserved set is the ASCII letters, the digits, hyphen (-), period (.), underscore (_) and tilde (~). These characters never need percent-encoding, and a normaliser decodes them if it finds them encoded.

The reserved characters are the general delimiters : / ? # [ ] @ and the sub-delimiters ! $ & ' ( ) * + , ; = . Each one is safe where it acts as a delimiter and must be percent-encoded where it is data.

The rule is positional rather than absolute. A character in the reserved set is left alone where it is doing the job of a delimiter and escaped where it is carrying data, so the same byte can be safe in the path and unsafe in the query of one address.

You can percent-encode the same string and percent-decode the same string to see both directions on one value.

HTML character references, in full

An HTML character reference starts with an ampersand and ends with a semicolon. A named reference uses a name from the HTML standard's table (&); a numeric one uses &# and decimal digits (A) or &#x and hexadecimal digits (A).

In HTML text only two things must be escaped: a less-than sign, and an ampersand that would otherwise start a character reference. Inside a quoted attribute value the quote character that closes it must be escaped as well.

Five names are predefined and carried by both XML and HTML: & for the ampersand, < for the less-than sign, > for the greater-than sign, " for the double quote and ' for the apostrophe.

A reference is resolved by the parser, so what a reader sees is the character and what the file holds is the reference. Escaping more than the rule asks for is safe; escaping less is what turns a stray angle bracket into a tag that was never written.

Reading one back is the same move in reverse: you can decode the same entities and see which characters they stand for.

Base64, in full

Base64 exists to carry data through channels that accept only US-ASCII text. It is an encoding, not encryption: any decoder reverses it.

Base64 writes data with 64 characters - A to Z, a to z, 0 to 9, plus (+) and slash (/) - and reserves the equals sign (=) for padding.

Base64 reads three bytes (24 bits) at a time and writes them as four characters of six bits each, so the output runs four characters for every three bytes - about a third larger than the input.

That growth is the price of the guarantee. Six bits of the output carry eight bits of the input, so a payload that has to survive a mail header or a JSON string pays a quarter of itself for the trip.

A data URI is data:, then an optional media type, then an optional ;base64, then a comma, then the data. With the media type left out it means text/plain;charset=US-ASCII.

You can run a string through the Base64 encoder to see the four-character groups for yourself, then run a Base64 string through the decoder to read back what it holds.

The same character in all three

Six characters, written every way the three schemes allow. Each line gives the character itself, then its percent triplet, then its Base64 form, then its HTML character reference.

character 'A' = percent 'A' (unreserved, left alone) = base64 'QQ==' = HTML A or A

character ' ' = percent '%20' = base64 'IA==' = HTML no character reference needed

character '&' = percent '%26' = base64 'Jg==' = HTML &

character '<' = percent '%3C' = base64 'PA==' = HTML &lt;

character ''' = percent '%27' = base64 'Jw==' = HTML &apos;

character 'é' = percent '%C3%A9' = base64 'w6k=' = HTML &#233; or &#xE9;

Two of those lines are worth reading twice. The letter A is unreserved, so percent-encoding leaves it exactly as it found it, and a space needs no character reference at all in markup — a container only escapes what would confuse it.

ASCII defines 128 characters, codes 0–127, using 7 bits; in practice each code is stored in one 8-bit byte with a leading 0.

é is U+00E9 and encodes as C3 A9 (2 bytes), which is where the two triplets in the é row above come from: a percent triplet stands for one byte, and a character outside ASCII is more than one byte.

Frequently Asked Questions

When should you use Base64 instead of percent-encoding?

When the payload is bytes rather than text: a key, a signature, a small image. Percent-encoding rewrites characters a URL cannot carry as themselves. Base64 carries data that was never text to begin with.

Can you put HTML entities in a URL?

Not as a way of encoding the URL. The parser resolves a character reference before the link is ever followed, so a named reference in an href reaches the network as the character it stands for. Anything the URL itself cannot carry still needs a percent triplet underneath.

Which encoding belongs in a query string?

Percent-encoding. A query string is part of a URL, so a value holding a reserved character has to arrive as triplets. If the page carrying that link is markup, character references are written on top of the triplets, not instead of them.

Do any of these encodings make data secure?

No. All three are reversible by design and none of them takes a key. Base64 is the one that looks like ciphertext, and it is not: any decoder reverses it.

What happens when encodings are nested?

You get one layer per pass, and each has to come off in the opposite order. A Base64 string placed in a URL is percent-encoded on top, so the plus and the slash in its alphabet arrive as triplets rather than as themselves.

Once you know which encoding you need, head back to the text encoding converter.