Как получить MIME Base64
- Вставьте текст в поле Ввод · текст. В поле Перенос строк уже выбрано 76 (MIME, LF).
- Не меняйте Кодировку (UTF-8), если в сообщении не объявлена другая кодировка, и укажите то же значение в заголовке
Content-Type. - Скопируйте Base64 с переносами из поля Результат · Base64 или нажмите Скачать, чтобы сохранить его в
base64.txt. - Для содержимого сертификатов и ключей переключите Перенос строк на 64 (PEM). Для HTTP, JSON и всего, где нужна одна строка, выберите Нет.
Что такое MIME Base64
Стандарт MIME (RFC 2045) позволяет почте передавать вложения, текст не на английском и HTML. Если тело части двоичное или полно байтов вне ASCII, отправитель кодирует его в Base64 и помечает заголовком Content-Transfer-Encoding: base64. Поверх обычного Base64 RFC 2045 добавляет правило длины строки: закодированные строки не длиннее 76 символов. В строку из 76 символов помещается 57 входных байтов.
Закодированная таким образом текстовая часть выглядит так; две строки Base64 выдал этот инструмент для фразы, приведённой ниже:
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
Q2Fmw6kgbWVudTogY3LDqG1lIGJyw7tsw6llLCBqYWxhcGXDsW8sIHNtw7ZyZ8Olc2JvcmQuIFRo
aXMgbGluZSBpcyBsb25nIGVub3VnaCB0byB3cmFwIGFmdGVyIDc2IGNoYXJhY3RlcnMu
Исходный текст: Café menu: crème brûlée, jalapeño, smörgåsbord. This line is long enough to wrap after 76 characters., 108 байт в UTF-8. Если декодировать обе строки вместе декодером Base64, получится та же фраза; перевод строки игнорируется.
Переводы строк, CRLF и размер
В поле Перенос строк есть два варианта на 76 колонок: 76 (MIME, LF) разделяет строки символом перевода строки (\n), а 76 (MIME, CRLF) парой \r\n. При передаче почта использует CRLF, а почтовые библиотеки сами приводят окончания строк при сериализации сообщения, так что для кода подходит LF. Если вы вставляете результат прямо в «сырой» файл .eml или в SMTP-сессию, выберите вариант с CRLF.
Перенос стоит немного места сверх обычных 33%:
| Вывод | Символов на 57 входных байт | Накладные расходы |
|---|---|---|
| Одна строка без переносов | 76 | 33,3% |
| Строки по 76 символов с LF | 77 | 35,1% |
| Строки по 76 символов с CRLF | 78 | 36,8% |
Ограничения размера почты действуют на закодированное сообщение, поэтому вложение в 10 МБ занимает примерно 13,7 МБ лимита. Точные цифры даст калькулятор размера, а как части письма складываются вместе, объясняет статья Base64 в электронной почте.
Encoded-words для заголовков
Заголовки вроде Subject и From не могут использовать Content-Transfer-Encoding. Текст заголовков вне ASCII записывается через encoded-words из RFC 2047: =?charset?B?base64?=. Чтобы собрать такое слово, закодируйте текст с Перенос строк = Нет и оберните результат вручную:
Subject: =?UTF-8?B?R3LDvMOfZSBhdXMgQmVybGlu?=
Это декодируется в Grüße aus Berlin. Одно encoded-word может быть не длиннее 75 символов; более длинные темы разбиваются на несколько encoded-words через пробел. Для текста, который почти целиком в ASCII, почтовые программы часто используют вместо этого форму ?Q?, основанную на quoted-printable.
MIME Base64 в коде и в командной строке
base64.encodebytes в Python переносит строки на 76 символах через \n и даёт те же строки, что и этот инструмент:
import base64
text = "Café menu: crème brûlée, jalapeño, smörgåsbord. This line is long enough to wrap after 76 characters."
print(base64.encodebytes(text.encode("utf-8")).decode("ascii"))
Для целых сообщений пакет email сам берёт на себя кодирование, заголовки и CRLF. В Linux GNU base64 по умолчанию переносит на 76, а openssl base64 переносит на 64:
base64 attachment.pdf > attachment.b64
openssl base64 -in attachment.pdf -out attachment.pem.b64
Чтобы, наоборот, разобрать «сырое» письмо, откройте его в декодере писем (EML), и он извлечёт тела и вложения.
Вопросы и ответы
Почему в MIME Base64 строки по 76 символов?
RFC 2045 устанавливает предел в 76 символов, с запасом ниже ограничения длины строки в почте в 998 символов (RFC 5322). 76 кратно 4, поэтому в каждой строке ровно 57 байт.
Отличается ли MIME Base64 от обычного Base64?
Алфавит и дополнение те же самые. Отличаются только переводы строк, а декодеры обязаны их игнорировать, так что варианты с переносами и без декодируются в одни и те же байты.
Нужно ли переносить Base64 в теме письма (Subject)?
Нет. В заголовках используются encoded-words из RFC 2047 вроде =?UTF-8?B?R3LDvMOfZQ==?=, и переводов строк в них быть не должно. Кодируйте тему с «Перенос строк» = «Нет» и держите каждое encoded-word не длиннее 75 символов.
Почему openssl выдаёт строки по 64 символа?
openssl base64 переносит на 64 символах, как принято в PEM, а GNU base64 и большинство почтовых библиотек переносят на 76. Декодируются оба варианта одинаково; если нужен результат, совпадающий с openssl, выберите здесь 64.