Quoted-Printable Decoder & Encoder

Paste email source full of =E2=80=99 and =20 and read it as intended — or encode text into quoted-printable for MIME email. Handles soft line breaks, a charset choice for old messages, and the =?UTF-8?Q?…?= encoded-words that appear in subject lines. Live, in your browser.

Quoted-printable = bytes as =XX: each non-printable byte becomes an equals sign plus two hex digits. ’ (UTF-8: E2 80 99) → =E2=80=99 It exists so mostly-ASCII text stays readable while surviving ancient 7-bit email systems — which is why an apostrophe from Word turns into nine characters of noise.

Decoding runs entirely in your browser — email content you paste is never uploaded, and the page works offline once loaded. That matters here more than for most tools: pasted email is usually private.

[ Ad slot — replace with AdSense / Ezoic code ]

Reading raw email source — the main use case

Open "show original" on almost any email and the body is quoted-printable: curly apostrophes as =E2=80=99, em dashes as =E2=80=94, non-breaking spaces as =C2=A0, every line ending in a stray =. You end up here when investigating a suspicious email's real contents, extracting text from an .eml file, debugging why your application's outgoing mail renders wrong, or salvaging a message from a corrupted mailbox export.

To decode correctly, the tool does three things in order: removes soft line breaks — an = at the very end of a line, which means "this line was wrapped for transport, rejoin it" and disappears entirely; converts each remaining =XX pair to a byte; and then interprets the byte sequence in the charset you select. That last step is why the charset menu exists: =E9 is é in Latin-1 but an invalid sequence in UTF-8. The message's own Content-Type: text/plain; charset="…" header tells you which to pick; modern mail is UTF-8, and Windows-1252 covers most older mail that isn't (it's Latin-1 plus the smart quotes and dashes in the 0x80–0x9F range, which is exactly where mystery characters from Outlook live).

Subject lines and sender names use a related wrapper, RFC 2047 encoded-words: =?UTF-8?Q?Caf=C3=A9_menu?=. The Q encoding inside is quoted-printable with two twists — underscores mean spaces, and the charset is declared inline. Leave the header-words option on and these decode too, each using its own declared charset.

Encoding: the rules the encoder follows

Encoding is the same transformation reversed, plus the RFC 2045 formatting rules that make output valid for a real MIME message: printable ASCII (except = itself) passes through literally; every other byte of the text's UTF-8 (or selected charset) encoding becomes =XX with uppercase hex; lines are wrapped at 76 characters using soft breaks, never splitting an =XX triple; and a space or tab that would land at the end of a line is encoded as =20/=09, because transport is allowed to strip trailing whitespace and the encoding must protect it.

Quoted-printable vs Base64

MIME offers both, and mailers choose per message part. QP keeps mostly-ASCII text human-readable in raw form and grows it only slightly (each non-ASCII byte triples, but there are few of them); Base64 turns everything into uniform blocks, unreadable but compact for data that's mostly non-ASCII. The rule of thumb encoders use: text in Latin scripts → quoted-printable; text in scripts where nearly every character is multi-byte (Chinese, Japanese, Arabic), plus attachments and images → Base64. That's why the German email you inspect is QP and the Japanese one is Base64.

Related tools

[ Ad slot — replace with AdSense / Ezoic code ]

Frequently asked questions

Why do emails look like this in the first place?

Because SMTP was standardized in 1982 for 7-bit ASCII, and the guarantee that every relay on a message's path handles 8-bit data cleanly never became absolute. MIME (1992) solved it by encoding message bodies into pure printable ASCII that any relay from any decade passes untouched — quoted-printable for readable text, Base64 for everything else. Modern servers mostly negotiate 8-bit transfer, but mail software still encodes defensively because a message's route is unpredictable. So the =E2=80=99 you're staring at is a 30-year-old compatibility layer doing its job.

What does =20 at the end of a line mean?

A protected trailing space. Mail transport is permitted to strip whitespace at line ends, so an encoder that needs a line to genuinely end in a space writes it as =20 (and a tab as =09), which nothing strips. You'll see it constantly in HTML email, where formatting whitespace lands at line boundaries. Decoded, it's just a space — but when encoding, this tool applies the same protection, which is one of the details that makes output safe to put in a real message.

The decoded text shows � replacement characters — what's wrong?

The bytes don't form valid sequences in the charset you selected — nearly always UTF-8 selected for a message that's actually Latin-1 or Windows-1252. Check the email's Content-Type header for the real charset, or just try Windows-1252: if =E9-style single-byte codes produced the �, that will resolve it. The reverse mistake (decoding UTF-8 as Latin-1) doesn't produce � but mojibake like é — if you see that, switch to UTF-8.

Why does a = sometimes remain in the decoded output?

A bare = not followed by two hex digits (and not at a line end) is technically invalid quoted-printable, and the standard's guidance is to leave it as-is rather than guess. This tool does that and counts these spots for you. It usually means the text was already partially decoded, or was mangled in copy-paste — often you can decode what remains by fixing the obvious break.