100% offline
Developer
Free · no signup
Updated

Quoted-Printable Encoder / Decoder

A Quoted-Printable Encoder / Decoder converts between raw bytes and the RFC 2045 =XX escape form used by email, handling soft line breaks, trailing whitespace and RFC 2047 encoded words — entirely in your browser.

CR and LF are treated as line breaks. Trailing whitespace is encoded and lines are wrapped at 76 characters with soft breaks, both of which RFC 2045 requires.

  • Decoded36 bytes
  • Bytes426f 6e6a 6f75 722c 2076 6f69 6369 2075 6e20 6361 66c3 a920 7472 c3a8 7320 6368 6175 642e

About Quoted-Printable Encoder / Decoder

Quoted-Printable is the encoding that keeps mostly-ASCII text readable while still surviving a 7-bit transport: a byte becomes =XX and everything printable stays as it is. The encoding is trivial and the two rules around it are what implementations get wrong. Trailing whitespace must be encoded, because a transport is allowed to strip a literal space at the end of a line — which is why a message can verify locally and fail after sending. And lines must not exceed 76 characters, with a line ending in a bare = being a soft break that carries no data; a decoder that treats it as data inserts a stray = every 76 bytes, and an encoder that omits it hands the wrapping decision to a transport that will make it in the wrong place. Both are handled here and both are reported. The other half of the tool is the form most people actually meet: the =?UTF-8?Q?...?= encoded word in a Subject or From header. Those follow different rules — an underscore means a space, the charset is declared inline per word rather than assumed, and whitespace between two adjacent encoded words is a separator that must be dropped rather than kept — so decoding a header with a body decoder is exactly why subject lines come out full of underscores. Both Q and B encoded words are decoded, since real headers mix them, and because the charset is read from the word rather than guessed you get é instead of é.

What Quoted-Printable Encoder / Decoder does

  • Encodes trailing whitespace as =20 and =09, which RFC 2045 requires
  • Wraps at 76 characters with soft line breaks, never splitting an escape
  • Decodes =?UTF-8?Q?...?= and =?UTF-8?B?...?= email headers
  • Reads the charset from the encoded word instead of assuming UTF-8
  • Drops the separator whitespace between adjacent encoded words, per RFC 2047
  • Treats CR and LF as data in binary mode, as line breaks in text mode
  • Reports lowercase hex, stray '=' and over-long lines as non-conforming
  • Shows the decoded bytes in hex, since the encoding is about bytes not text

When to reach for Quoted-Printable Encoder / Decoder

  • Reading a Subject line that arrived as =?UTF-8?Q?...?= in a log or a raw message
  • Working out why an email body is full of =C3=A9 or stray = characters
  • Checking whether a mail library is encoding trailing whitespace correctly
  • Encoding a header value by hand while debugging an SMTP conversation

How to use Quoted-Printable Encoder / Decoder

  1. 01

    Choose where it came from

    Message body for ordinary content, or Header for anything that looks like =?UTF-8?Q?...?=. The two follow different rules and picking the wrong one is the usual cause of a confusing result.

  2. 02

    Paste the text

    Decoding is the default. Soft line breaks, transport padding and mixed Q and B words are all handled.

  3. 03

    Set the charset if needed

    Quoted-Printable encodes bytes, not text. Headers declare their own charset; for a body it comes from the message's Content-Type, and getting it wrong is what turns é into é.

  4. 04

    Read the notes

    Anything non-conforming in the input is reported — lowercase hex, a stray '=', over-long lines, or trailing whitespace that was never encoded and may already have been stripped.

When to use Quoted-Printable Encoder / Decoder vs alternatives

AlternativeUse Quoted-Printable Encoder / Decoder when…Use the alternative when…
A generic online quoted-printable decoderyour input is a header rather than a body. Those decoders miss that an underscore is a space and that the charset is declared per word, which is why they return underscores and mojibake.you have a plain body and only want the text.
Python's quopri moduleyou want the non-conforming parts of the input pointed out rather than silently accepted, and you do not want to write a script to read one header.you are decoding messages in bulk from a script.
Base64the content is mostly ASCII and you want it to stay readable in transit and in a diff.the content is mostly binary — Quoted-Printable triples the size of arbitrary bytes, where Base64 adds a third.

Frequently asked questions

Why does my decoded text contain stray '=' characters at the end of lines?
Those are soft line breaks, not data. RFC 2045 limits a line to 76 characters, and an encoder that needs to break a longer line puts a '=' at the end to say the break is not part of the content. A decoder must remove both the '=' and the line break; one that does not leaves a '=' every 76 bytes. This tool removes them and tells you how many it removed.
Why is my email subject full of underscores?
Because it was decoded with a body decoder rather than a header one. Inside an RFC 2047 encoded word — anything of the form =?charset?Q?...?= — an underscore means a space, a shorthand that only applies there. In a message body an underscore is just an underscore. Switch the context to Header and the spaces come back.
Why do I see é instead of é?
Because the bytes were read with the wrong charset. Quoted-Printable encodes bytes, and something else has to say what those bytes mean: =C3=A9 is é in UTF-8, but read as ISO-8859-1 the same two bytes are à and ©. For a header the charset is declared in the encoded word itself, which is why this tool reads it from there instead of guessing. For a body it comes from the message's Content-Type header.
Why must trailing spaces be encoded?
Because a transport is allowed to strip them. RFC 2045 lets a space or tab appear literally mid-line but not at the end of one, so a conforming encoder writes it as =20 or =09. An encoder that leaves it produces a message whose content changes somewhere in transit — which is a good way to make a signature that verified locally fail after sending. When decoding, this tool tells you if the input has unencoded trailing whitespace, because it means the data may already have been altered.
When should I use Quoted-Printable instead of Base64?
When the content is mostly ASCII. Quoted-Printable leaves printable characters alone, so an English email with a few accents stays readable in a raw message and in a diff, at a cost of three characters per encoded byte. On arbitrary binary that cost dominates — every byte becomes =XX, tripling the size — where Base64 adds a flat third. The rule of thumb the RFC itself gives: Quoted-Printable for mostly-text, Base64 for mostly-binary.
What is the difference between the Q and B encodings in a header?
They are the two ways RFC 2047 allows an encoded word to carry non-ASCII. Q is quoted-printable with extra restrictions, and it keeps the text mostly readable, so it suits a subject that is mostly ASCII. B is straight Base64 and is more compact once most of the characters need encoding, which is why headers in Japanese or Russian usually use it. Real headers mix both, sometimes in the same line, so this tool decodes either without being told which.

Related concepts