DevToys Pro

бесплатные веб-инструменты для разработчиков

Блог
Оцените нас:
Попробуйте расширение для браузера:
← Назад к блогу

Quoted-Printable: кодирование для email

12 мин чтения

Если вы когда-либо изучали исходный код email-сообщения и видели последовательности вроде =3D, =20 или загадочные переносы строк =\r\n, вы смотрели на кодирование Quoted-Printable. Этот формат MIME-кодирования разработан для сохранения email-контента в основном читабельным, при этом безопасно передавая специальные символы через email-системы, которые исторически были ограничены 7-битным ASCII.

Это руководство объясняет, что такое кодирование Quoted-Printable, как оно работает, когда использовать его вместо Base64, и как отлаживать проблемы кодирования email с помощью кодировщика/декодера Quoted-Printable.

Что такое кодирование Quoted-Printable?

Quoted-Printable (часто сокращается как QP-кодирование) — это одна из двух основных кодировок передачи контента, определенных в стандарте MIME (вторая — Base64). Она была создана для кодирования email-контента, который в основном состоит из обычного ASCII-текста с редкими не-ASCII символами или специальными символами.

Ключевые характеристики кодирования Quoted-Printable:

  • ASCII-символы (33-126, кроме =) остаются без изменений
  • Пробелы и табуляции могут оставаться как есть в большинстве контекстов
  • Не-ASCII и специальные символы кодируются как =XX, где XX — шестнадцатеричное значение байта
  • Строки не должны превышать 76 символов, соблюдается с помощью мягких переносов строк (= в конце строки)
  • В основном читабельно человеком, когда контент преимущественно ASCII

Правила кодирования

Правило 1: Кодировать непечатаемые и специальные символы

Любой байт, который не является печатаемым ASCII-символом (или сам знак равенства), должен быть закодирован как =XX:

СимволЗначение байта (Hex)Quoted-Printable
=0x3D=3D
Пробел в конце строки0x20=20
Табуляция в конце строки0x09=09
Не-ASCII (é)0xC3 0xA9 (UTF-8)=C3=A9

Правило 2: Мягкие переносы строк

Строки длиннее 76 символов должны быть разделены с помощью мягкого переноса строки: знак равенства, за которым следует CRLF (=\r\n). Это сообщает декодеру, что строка продолжается на следующей строке, и знак равенства должен быть удален во время декодирования.

Это очень длинная строка текста, которая превышает лимит в 76 символов и=
 должна быть разделена с помощью мягкого переноса для соответствия MIME.

// Декодируется в:
Это очень длинная строка текста, которая превышает лимит в 76 символов и должна быть разделена с помощью мягкого переноса для соответствия MIME.

Важно: Пробел после = на продолжающейся строке является частью исходного контента, а не добавлен кодированием. Если изначально не было пробела, продолжение начинается сразу без ведущего пробела.

Правило 3: Пробелы в конце строки

Пробелы и табуляции в конце строки должны быть закодированы, потому что некоторые email-системы удаляют завершающие пробелы:

// Оригинал: "Привет мир  " (два завершающих пробела)
// Закодировано: "Привет мир=20=20"

// Это предотвращает удаление завершающих пробелов email-системами

Реальный пример email

Вот как выглядит заголовок и тело реального MIME email-сообщения с QP-кодированием:

From: sender@example.com
To: recipient@example.com
Subject: =?UTF-8?Q?Test:_Special_Characters_=C3=A9=C3=B1?=
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Привет,

Это email содержит специальные символы: =C3=A9 (é), =C3=B1).
Знаки равенства должны быть закодированы: 2 + 2 =3D 4

Длинные строки переносятся с мягкими разрывами:
Это очень длинная строка, которая выходит за пределы семидесяти шести симв=
олов и требует разделения.

С уважением

Обратите внимание, что заголовок Subject также использует форму кодирования Quoted-Printable (называемую "Q-кодированием" или "RFC 2047 кодированием"), но с другим синтаксисом: =?charset?Q?encoded_text?=. Подчеркивания представляют пробелы в кодировании заголовка.

Quoted-Printable vs Base64

MIME определяет две основные кодировки передачи контента. Выбор между Quoted-Printable и Base64 зависит от типа контента:

АспектQuoted-PrintableBase64
Лучше дляВ основном ASCII-текст с малым количеством не-ASCII символовБинарные данные, изображения, не-текстовые файлы
ЧитабельностьЧитабельно человеком для ASCII-частейПолностью закодировано, не читабельно
OverheadНизкий для ASCII (~1-3% для английского)Фиксированный 33% overhead независимо от контента
Длина строки76 символов, мягкие переносы76 символов, жесткие переносы
Случай использованияТело email, HTML emailВложения, изображения, PDF файлы

Когда использовать Quoted-Printable

Выбирайте Quoted-Printable когда:

  • Контент в основном обычный текст или HTML
  • Большинство символов — стандартный ASCII (A-Z, a-z, 0-9, обычная пунктуация)
  • Только редкие символы с диакритикой, эмодзи или символы появляются
  • Вы хотите, чтобы контент оставался в основном читабельным в исходном коде
  • Тело email на языках, использующих латинское письмо

Когда использовать Base64

Выбирайте Base64 когда:

  • Контент — бинарные данные (изображения, PDF, ZIP файлы)
  • Более ~30% байтов не-ASCII
  • Контент интенсивно использует нелатинские алфавиты (китайский, арабский, кириллица)
  • Вложения любого типа файлов

Для Base64 кодировщика/декодера смотрите DevToys Pro Base64 инструмент.

Распространённые случаи использования

Случай 1: Текстовый email с символами с диакритикой

Исходное сообщение:
"Café résumé naïve"

Quoted-Printable закодировано:
"Caf=C3=A9 r=C3=A9sum=C3=A9 na=C3=AFve"

// Только не-ASCII символы закодированы
// Английские слова остаются читабельными

Случай 2: Тело HTML email

Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
<body>
<p>Добро пожаловать в нашу рассылку!</p>
<p>Специальное предложение: скидка 50=25</p>
<p>Местоположение: Caf=C3=A9 &#201;toile</p>
</body>
</html>

// % закодирован как =25 (0x25 в hex)
// é закодирован как =C3=A9 (байты UTF-8)

Случай 3: Email с длинными URL

Оригинал:
"Посетите наш сайт: https://example.com/products?category=electronics&sort=price&filter=new"

Quoted-Printable закодировано:
"Посетите наш сайт: https://example.com/products?category=3Delectronics&s=
ort=3Dprice&filter=3Dnew"

// Обратите внимание:
// 1. = закодирован как =3D
// 2. Мягкий перенос (=) разделяет длинную строку
// 3. & остается как есть (печатаемый ASCII)

Отладка проблем кодирования email

Проблема 1: Знаки равенства появляются в тексте email

Если ваш email отображает буквально =3D, =20 или другие последовательности =XX, email-клиент не смог декодировать кодирование Quoted-Printable.

Распространённые причины:

  • Отсутствует или неправильный заголовок Content-Transfer-Encoding: quoted-printable
  • Email-клиент не поддерживает Quoted-Printable
  • Email был переслан и перекодирован неправильно

Исправление: Убедитесь, что MIME-заголовки правильно объявляют кодирование. Используйте декодер Quoted-Printable для ручного декодирования и проверки контента.

Проблема 2: Переносы строк появляются в неправильных местах

Если вы видите неожиданные переносы строк в словах, email, вероятно, был закодирован с жесткими переносами строк вместо мягких:

// Неправильно: жесткий перенос строки (нет =)
Это длинная строка, которая переносится
здесь без маркера мягкого переноса

// Отображается как две строки с разрывом посередине предложения

// Правильно: мягкий перенос строки (=)
Это длинная строка, которая переносится=
 здесь с маркером мягкого переноса

// Отображается как одна непрерывная строка

Проблема 3: Потеряны завершающие пробелы

Если пробелы в конце строк исчезают, они не были закодированы. Email-системы часто удаляют завершающие пробелы из обычного текста. Если сохранение завершающих пробелов критично, они должны быть закодированы как =20 или =09 (табуляция).

Кодирование и декодирование Quoted-Printable

Алгоритм ручного кодирования

Для кодирования текста как Quoted-Printable:

  1. Для каждого байта во входе:
    • Если печатаемый ASCII (33-60, 62-126): выводить как есть (кроме = → кодировать как =3D)
    • Если пробел или табуляция: выводить как есть, если не в конце строки (тогда кодировать как =20 или =09)
    • Иначе: кодировать как =XX (шестнадцатеричное значение байта)
  2. Если строка превышает 76 символов, вставить мягкий перенос =\r\n
  3. Убедиться, что строки заканчиваются CRLF (\r\n)

Алгоритм ручного декодирования

Для декодирования текста Quoted-Printable:

  1. Для каждого символа во входе:
    • Если =XX: конвертировать hex XX в значение байта
    • Если =\r\n (мягкий перенос): пропустить, продолжить на следующей строке
    • Иначе: вывести символ как есть
  2. Восстановить многобайтовые UTF-8 последовательности из декодированных байтов

Использование инструмента Quoted-Printable

Для практического кодирования и декодирования используйте специальный кодировщик/декодер Quoted-Printable. С помощью DevToys Pro инструмента Quoted-Printable вы можете:

  • Кодировать обычный текст или HTML для передачи email
  • Декодировать тела Quoted-Printable email для проверки контента
  • Тестировать, как кодируются специальные символы
  • Отлаживать проблемы рендеринга email, декодируя исходный код
  • Проверять, что мягкие переносы строк вставлены правильно

MIME кодирование заголовков (Q-кодирование)

Email-заголовки (Subject, From, To) используют вариант, называемый Q-кодированием или RFC 2047 кодированием. Оно следует похожим правилам, но использует другой синтаксис обёртки:

Subject: =?UTF-8?Q?Caf=C3=A9_R=C3=A9sum=C3=A9?=

// Формат: =?charset?Q?encoded_text?=
// _ представляет пробел в заголовках
// То же hex-кодирование, что и в теле Quoted-Printable

Ключевые отличия от Quoted-Printable тела:

  • Пробелы кодируются как подчеркивание (_) вместо =20
  • Обернуто в разделители =?charset?Q?...?=
  • Используется исключительно в заголовках, не в теле сообщения
  • Ограничено 75 символами на encoded-word

Лучшие практики

1. Выбирайте правильную кодировку

Используйте Quoted-Printable для текстового контента, Base64 для бинарных вложений. Не используйте Quoted-Printable для изображений или файлов — они значительно раздуются.

2. Устанавливайте правильные MIME-заголовки

Всегда объявляйте кодирование в MIME-заголовках:

Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

// Оба заголовка необходимы для правильного декодирования

3. Используйте мягкие переносы строк правильно

Убедитесь, что мягкие переносы строк вставляются до лимита в 76 символов и используют правильные окончания строк CRLF (\r\n, а не просто \n).

4. Тестируйте с несколькими клиентами

Тестируйте закодированные email в нескольких email-клиентах (Gmail, Outlook, Apple Mail, Thunderbird), чтобы проверить, что декодирование работает правильно на разных платформах.

5. Используйте библиотеки для production

Для production отправки email используйте проверенные библиотеки, которые обрабатывают MIME-кодирование автоматически:

// Python
from email.mime.text import MIMEText
msg = MIMEText("Café", 'plain', 'utf-8')
# Автоматически применяет Quoted-Printable если подходит

// Node.js (Nodemailer)
const mailOptions = {
  text: 'Café',
  encoding: 'quoted-printable'
};

Краткая справка

ПаттернЗначениеПример
=XXЗакодированный байт (hex)=3D это =
=\r\nМягкий перенос строки (игнорируется декодером)Разделяет длинные строки
=20Пробел (в конце строки)Сохраняет завершающий пробел
=09Табуляция (в конце строки)Сохраняет завершающую табуляцию
76 символов максЛимит длины строкиВставить мягкие переносы до лимита
=?charset?Q?text?=Кодирование заголовка (Q-кодирование)=?UTF-8?Q?Caf=C3=A9?=

Заключение

Кодирование Quoted-Printable — это элегантное решение для передачи email, которое сохраняет в основном ASCII-текст читабельным человеком, при этом безопасно кодируя не-ASCII символы и специальные символы. Понимание, когда использовать Quoted-Printable вместо Base64, как работают мягкие переносы строк и как отлаживать проблемы кодирования, поможет вам создавать надежные email-системы и устранять проблемы рендеринга.

Ключевые выводы:

  • Quoted-Printable сохраняет ASCII-текст читабельным, кодирует не-ASCII как =XX
  • Мягкие переносы строк (=\r\n) разделяют длинные строки без влияния на декодированный вывод
  • Используйте QP для текста, Base64 для бинарных данных и вложений
  • Email-заголовки используют вариант Q-кодирования с подчеркиваниями для пробелов
  • Всегда устанавливайте MIME-заголовки правильно для корректного декодирования клиентом

Для тестирования и отладки email-кодирования используйте кодировщик/декодер Quoted-Printable для кодирования контента перед отправкой или декодирования исходного кода email для проверки, как обрабатываются специальные символы и переносы строк.