Upload a file
  1. base64hub
  2. Web & token tools
  3. Quoted-printable

Quoted-Printable Encoder and Decoder

Decode quoted-printable email text such as Gr=C3=BC=C3=9Fe back to Grüße, or encode text the way mail software does: =XX for bytes that need it and soft line breaks at 76 characters.

Free no sign-up, no limits Local nothing uploaded Python byte-exact with binascii.b2a_qp Updated Oct 27, 2026
Input 0Bytes 0 BOutput 0

Processed in your browser. This page cannot send your data anywhere – how we know

How to decode quoted-printable

  1. Click Quoted-printable → Text above the tool to switch to decoding.
  2. Paste the encoded text, for example a body part copied from an email’s source, into the input.
  3. Read the text in the output. If accented letters look wrong, set Charset under the output to the charset named in the part’s Content-Type header, such as charset=iso-8859-1.
  4. Copy output or Download. Soft line breaks are joined and every =XX is turned back into its byte.

To encode, leave the direction on Text → Quoted-printable and type or paste the text. Charset under the input decides which bytes non-ASCII characters become.

How quoted-printable works

Quoted-printable (RFC 2045, section 6.7) keeps text readable where it can and escapes only what it must:

  • Printable ASCII characters stay as they are, except =.
  • Every other byte is written as = plus two uppercase hex digits. In UTF-8 that means each non-ASCII character becomes two to four escapes.
  • = itself becomes =3D.
  • A space or tab at the end of a line becomes =20 or =09.
  • Lines are at most 76 characters. Longer ones are split with a soft line break: an = at the end of the line, which the decoder removes.
TextQuoted-printable
cafécaf=C3=A9
Grüße aus MünchenGr=C3=BC=C3=9Fe aus M=C3=BCnchen
100% = €5100% =3D =E2=82=AC5
<p style="color:red">Hi</p><p style=3D"color:red">Hi</p>
Caf=E9 decoded as ISO-8859-1Café

In the last row =E9 is a single byte: é in ISO-8859-1 and Windows-1252, and invalid on its own in UTF-8, so the result depends on the charset you decode with.

Text mode and binary mode

By default the encoder treats the input as text. Line breaks stay real line breaks, and, as in Python’s binascii.b2a_qp, if the first line ends in CRLF a bare LF later on becomes CRLF too. That is right for email text, but it changes the bytes.

Tick Encode line breaks (binary) when the exact bytes matter. Line breaks are then written as =0D and =0A, so Hello, CRLF, World becomes Hello=0D=0AWorld, and decoding gives back exactly what went in. For real binary data such as images, Base64 is the better choice anyway.

Quoted-printable or Base64 in email

Mail software picks the Content-Transfer-Encoding per MIME part. Quoted-printable suits text that is mostly ASCII, because it stays readable and grows little. Base64 has a fixed overhead of about 33% and wins once most bytes need escaping:

TextUTF-8 bytesQuoted-printableBase64
Grüße aus München2032 characters28 characters
Привет, мир (Russian)2056 characters28 characters

Even German text with three non-ASCII letters in 17 characters is already larger in quoted-printable than in Base64; Cyrillic is twice the Base64 size. To produce the Base64 form with the 76-character lines email requires, use the MIME Base64 encoder. Base64 in email explains how both encodings appear in a message, including attachments and encoded headers.

Reading a whole email

Copying one body part out of a raw message works for a quick look. For a complete .eml file, the EML decoder parses the headers, decodes quoted-printable and Base64 parts with their declared charsets, and lists attachments for download. Quoted-printable also appears outside email, for example in vCard 2.1 files with ENCODING=QUOTED-PRINTABLE; paste the value after the colon here.

Quoted-printable in code

import quopri
quopri.encodestring("café".encode("utf-8"))            # b'caf=C3=A9'
quopri.decodestring(b"caf=C3=A9 =3D 5=E2=82=AC").decode("utf-8")   # 'café = 5€'

Python’s email package applies the right decoding automatically: msg.get_payload(decode=True) returns the decoded bytes of a part, whichever transfer encoding it uses. The Python page covers the Base64 side.

FAQ

What does =3D mean in an email?

It is an encoded equals sign. In quoted-printable = starts an escape, so a literal = has to be written as =3D, its byte value in hex. You see it a lot in HTML email, as in style=3D"color:red".

Why do lines in the email source end with =?

That is a soft line break. Quoted-printable lines may be at most 76 characters, so longer lines are split and each break is marked with a trailing =. A decoder joins the pieces back into one line.

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

An encoded space. Mail systems may strip trailing spaces, so quoted-printable protects a space or tab at the end of a line by writing it as =20 or =09.

How do I decode quoted-printable in Python?

quopri.decodestring(data) or binascii.a2b_qp(data) return bytes; call .decode("utf-8") or whichever charset the Content-Type header names.

Can it decode =?UTF-8?Q?...?= subject lines?

Not on this page. Those are RFC 2047 encoded words, which use a related Q encoding with _ for spaces. The EML decoder decodes them in headers, along with quoted-printable bodies.