# Base64, URL and HTML encoder and decoder

> Encode or decode Base64, URL-safe Base64, URL percent-encoding, HTML entities, hex bytes and Unicode code points, with UTF-8 and UTF-16 byte counts.

Versione interattiva: https://www.calcopenly.com/it/programming/text-encoder-decoder
Argomento: Calcolatori di programmazione e tecnologia

Every scheme here starts from the text's UTF-8 bytes. Base64 regroups each 3 bytes into four 6-bit values drawn from a 64-character alphabet (RFC 4648), so the output is 4 × ⌈n ÷ 3⌉ characters. Percent-encoding writes every byte outside A–Z, a–z, 0–9 and - . _ ~ as %XX (RFC 3986), HTML escaping replaces & < > " and ' with character references, and hex writes two digits per byte.

Developers use it to put binary data in JSON or email, build query strings, read JWTs and track down character-set problems. The default, "Café & crème, 5 €", is 17 characters but 21 UTF-8 bytes, because é and è take 2 bytes each and € takes 3, and its Base64 form is 28 characters.

A decoding error names the bad character and its position, and bytes that aren't valid UTF-8 show as U+FFFD (�).

## Dati

- **Encoding** (opzioni: Base64, Base64 (URL-safe), URL percent-encoding, HTML entities, Hex bytes, Unicode code points)
- **Direction** (opzioni: Encode, Decode)
- **Testo**
- **Encoded text**: Whitespace and line breaks between Base64 or hex characters are ignored.
- **Keep = padding**: JWTs and most URL uses drop the padding.
- **Spaces as +**: HTML form encoding (application/x-www-form-urlencoded); off follows RFC 3986 and writes %20.
- **Also encode non-ASCII characters**: Writes é as &#233; for pages that aren't served as UTF-8.
- **Byte separator** (opzioni: Space, None, Colon)

## Risultati

- Risultato — risultato principale
- Characters (code points)
- UTF-8 bytes
- UTF-16 code units
- Result length (characters)
- UTF-8 bytes (hex)
- UTF-16 code units (hex)

## Formula

$$
\begin{aligned} \text{Base64 length} &= 4\left\lceil \frac{n}{3} \right\rceil \\ \text{hex length} &= 2n \\ n &= \text{UTF-8 bytes} \end{aligned}
$$

## Esempi svolti

### Base64 of “foob” (two padding characters)

- Encoding: Base64
- Direction: Encode
- Testo: foob
- **Risultato: Zm9vYg==**
- **UTF-8 bytes: 4**
- **Result length: 8 characters**
- Fonte di verifica: RFC 4648 §10 test vectors; Python 3.8 base64.b64encode(b'foob') and len() of input and output

### Base64 of an empty string

- Encoding: Base64
- Direction: Encode
- **Risultato: **
- **UTF-8 bytes: 0**
- **Result length: 0 characters**
- Fonte di verifica: RFC 4648 §10: BASE64("") = ""

### URL-safe Base64 without padding

- Encoding: Base64 (URL-safe)
- Direction: Encode
- Testo: <<???>>
- **Risultato: PDw_Pz8-Pg**
- **Result length: 10 characters**
- Fonte di verifica: Python 3.8 base64.urlsafe_b64encode(b'<<???>>').rstrip(b'=') (10 characters); the standard alphabet gives PDw/Pz8+Pg==

### Decode Base64 to Chinese text

- Encoding: Base64
- Direction: Decode
- Encoded text: 5L2g5aW9IOS4lueVjA==
- **Risultato: 你好 世界**
- **Characters (code points): 5**
- **UTF-8 bytes: 13**
- **UTF-16 code units: 5**
- Fonte di verifica: Python 3.8 base64.b64decode('5L2g5aW9IOS4lueVjA==').decode('utf-8'); len() of the text, its UTF-8 bytes and its UTF-16-LE bytes ÷ 2

### Decode unpadded Base64

- Encoding: Base64
- Direction: Decode
- Encoded text: Zm9vYg
- **Risultato: foob**
- Fonte di verifica: RFC 4648 §10 (Zm9vYg== is “foob”) with the padding removed; Python 3.8 base64.b64decode('Zm9vYg==')

### Percent-encode a query value

- Encoding: URL percent-encoding
- Direction: Encode
- Testo: a b&c=d/é?
- **Risultato: a%20b%26c%3Dd%2F%C3%A9%3F**
- **UTF-8 bytes: 11**
- Fonte di verifica: Python 3.8 urllib.parse.quote('a b&c=d/é?', safe=''); len(s.encode('utf-8')) = 11

## Domande

### Why does Base64 make data about 33% larger?

Base64 carries 6 bits in each output character against 8 bits in each input byte, so every 3 bytes become 4 characters, a ratio of 4 to 3, plus up to 2 = padding characters at the end. 21 bytes become 28 characters, and 1 MB of binary becomes about 1.33 MB. MIME email (RFC 2045) also breaks the output into lines of at most 76 characters, which adds a little more.

### What is the difference between Base64 and Base64URL?

Base64URL (RFC 4648 §5) replaces the two characters that clash with URLs and file names, + and /, with - and _, and usually drops the = padding. JSON Web Tokens (RFC 7519) use it for all three of their parts. The text <<???>> is PDw/Pz8+Pg== in standard Base64 and PDw_Pz8-Pg in the URL-safe form, 10 characters instead of 12.

### Is Base64 a form of encryption?

No. Base64 is a reversible encoding with no key, so anyone can decode it in one step; it only makes binary data safe to carry as text. HTTP Basic authentication (RFC 7617), for example, sends user:password in Base64, which is why it is only safe over HTTPS. To protect data, encrypt it first, for example with AES-256, and then Base64-encode the ciphertext if it must travel as text.

### Should a space be URL-encoded as %20 or +?

Both appear, in different places. RFC 3986, which governs URLs, encodes a space as %20, while HTML form submissions (application/x-www-form-urlencoded) write it as +. So a+b in a form's query string means a b, but in a URL path the + is a literal plus. JavaScript's encodeURIComponent gives %20, and Python's urllib.parse.quote_plus gives +.

### How many bytes does a character take in UTF-8?

One to four. Code points below U+0080 (ASCII) take 1 byte, those up to U+07FF take 2 (é, ñ, Greek, Cyrillic), those up to U+FFFF take 3 (€ and most Chinese characters) and the rest take 4, including emoji such as 😀 (U+1F600). So A€😀 is 3 characters, 8 UTF-8 bytes and 4 UTF-16 code units, because 😀 needs a surrogate pair in UTF-16 (RFC 3629).

### Quanto è preciso «Base64, URL and HTML encoder and decoder»?

La precisione dipende dai dati inseriti e dalle ipotesi del metodo. Il calcolo decimale usa 50 cifre significative, ma stime, metodi numerici e dati di origine possono essere meno precisi; l’arrotondamento visualizzato non elimina questi limiti. Esempi svolti verificati con fonti indipendenti: 17. Per esempio, «Base64 of “foob” (two padding characters)» viene verificato con RFC 4648 §10 test vectors; Python 3.8 base64.b64encode(b'foob') and len() of input and output.

### Da dove proviene il metodo?

RFC 4648 — The Base16, Base32, and Base64 Data Encodings; RFC 3986 §2 — URI characters and percent-encoding; RFC 3629 — UTF-8, a transformation format of ISO 10646; WHATWG HTML — Named character references; The Unicode Standard, §3.9 Unicode encoding forms.

## Fonti

- [RFC 4648 — The Base16, Base32, and Base64 Data Encodings](https://www.rfc-editor.org/rfc/rfc4648)
- [RFC 3986 §2 — URI characters and percent-encoding](https://www.rfc-editor.org/rfc/rfc3986#section-2)
- [RFC 3629 — UTF-8, a transformation format of ISO 10646](https://www.rfc-editor.org/rfc/rfc3629)
- [WHATWG HTML — Named character references](https://html.spec.whatwg.org/multipage/named-characters.html)
- [The Unicode Standard, §3.9 Unicode encoding forms](https://www.unicode.org/versions/latest/core-spec/chapter-3/)
