Percent Encoding Tool
Encode and decode text using percent encoding with our free online tool. Percent encoding (also called URL encoding) represents characters as %XX hexadecimal values, enabling safe transmission of any character through URL-restricted contexts.
Percent Encoding Reference
| Hex Value | Character | Category |
|---|---|---|
| %00-%1F | Control chars | Non-printable |
| %20 | Space | Whitespace |
| %21 | ! | Reserved in some contexts |
| %22 | " | Unsafe |
| %23 | # | Fragment delimiter |
| %25 | % | Encoding character itself |
| %2F | / | Path delimiter |
| %3F | ? | Query delimiter |
RFC 3986 Character Classes
The URL specification defines these character categories:
- Unreserved (never encoded): A-Z, a-z, 0-9, - . _ ~
- Reserved (encoded when not delimiters): : / ? # [ ] @ ! $ & ' ( ) * + , ; =
- Unsafe (always encoded): spaces, <, >, {, }, |, \, ^,
, and non-ASCII
Percent Encoding Implementation
`javascript
function percentEncode(text, options = {}) {
const { encodeReserved = true, charset = 'utf-8' } = options;
// Convert to UTF-8 bytes
const encoder = new TextEncoder();
const bytes = encoder.encode(text);
// Unreserved characters per RFC 3986
const unreserved = /[A-Za-z0-9\-._~]/;
let encoded = '';
for (const byte of bytes) {
const char = String.fromCharCode(byte);
if (unreserved.test(char)) {
encoded += char;
} else {
encoded += '%' + byte.toString(16).toUpperCase().padStart(2, '0');
}
}
return {
encoded,
byteCount: bytes.length,
encodedLength: encoded.length
};
}
// Strict RFC 3986 encoding
function rfc3986Encode(text) {
return encodeURIComponent(text).replace(/[!'()*]/g, c =>
'%' + c.charCodeAt(0).toString(16).toUpperCase()
);
}
`
Percent Encoding Standards
Different systems use slightly different percent encoding rules. Our tool supports RFC 3986 (URIs), HTML5 form encoding, and legacy encodings. Understanding which standard applies helps prevent encoding issues in your applications.
Encoding Is Not Encryption
Base64 and percent-encoding both make data safe to *transport*. Neither makes it secret ā
both are trivially reversible by design, with no key involved. A Base64 string in a URL, a
cookie or a header is readable by anyone who sees it.
| Purpose | Use |
|---|---|
| Safe transport of binary over text | Base64 |
| Safe transport of text in a URL | Percent-encoding |
| Confidentiality | AES-GCM, TLS |
| Integrity | HMAC, a digital signature |
| Password storage | bcrypt, scrypt, Argon2 |
Size Costs
Base64 expands data by exactly 4/3 ā three bytes become four characters ā plus padding. A
100 KB image becomes about 133 KB as a data URI, and it cannot be cached separately from the
document that carries it. Inline small icons; link everything else.
Percent-encoding expands unpredictably: an ASCII character that needs escaping becomes three
characters, and a non-ASCII character becomes three per UTF-8 byte. Ć© is %C3%A9 ā six
characters for one letter.
UTF-8 Is the Only Sane Default
Every encoding decision on the modern web assumes UTF-8. Where it goes wrong:
btoathrows on non-Latin-1 input.Encode to UTF-8 bytes first:
btoa(String.fromCharCode(...new TextEncoder().encode(text))).
atobreturns Latin-1.Decode back withnew TextDecoder().decode(bytes).- A BOM breaks parsers. Excel writes one at the start of CSV exports; strip it before
parsing.
Length is ambiguous."šØāš©āš§".lengthis 8 in JavaScript, 1 to a reader. Use
Intl.Segmenter` when the count is shown to a person.