Кодирование передачи контента 7 бит или 8 бит

88

При отправке содержимого электронной почты необходимо установить заголовок «Content Transfer Encoding». Я заметил множество заголовков писем, которые я получил. Некоторые электронные письма используют «7 бит», а некоторые - «8 бит».

В чем разница между этими двумя? Что рекомендуется? Требуется ли какая-либо специальная кодировка для тела письма, чтобы установить эти заголовки?

махи
источник
Я не думаю, что нужно устанавливать этот заголовок, не так ли? Я начинаю работать с электронной почтой и видел электронные письма без нее - очень простые, не состоящие из нескольких частей, сообщения только в формате ASCII.
osullic,

Ответы:

280

Это может быть немного сложно для чтения, но в разделе «Content-Transfer-Encoding» RFC 1341 есть все подробности:

http://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html

Ситуация становится все хуже и хуже. Вот мое резюме:

Задний план

SMTP, по определению (RFC 821), ограничивает почту строками из 1000 символов по 7 бит каждая. Это означает, что ни один из байтов, которые вы отправляете по конвейеру, не может иметь старший бит («самый высокий порядок»), установленный в «1».

Контент, который мы хотим отправить, часто не подчиняется этому ограничению. Подумайте о файле изображения или текстовом файле, который содержит символы Unicode: байты этих файлов часто имеют 8-й бит, установленный на «1». SMTP не позволяет этого, поэтому вам нужно использовать «кодировку передачи», чтобы описать, как вы работали с несоответствием.

Значения в Content-Transfer-Encodingзаголовке описывают правило, которое вы выбрали для решения этой проблемы.

7-битное кодирование

7bitпросто означает «Мои данные состоят только из символов US-ASCII, которые используют только младшие 7 бит для каждого символа». Вы в основном гарантируете, что все байты в вашем контенте уже соответствуют ограничениям SMTP, и поэтому не требуют особой обработки. Вы можете просто читать как есть.

Обратите внимание, что когда вы выбираете 7bit, вы соглашаетесь с тем, что все строки в вашем контенте имеют длину менее 1000 символов.

Пока ваш контент соответствует этим правилам, 7bitэто лучшая кодировка передачи, поскольку не требуется дополнительной работы; вы просто читаете / записываете байты по мере их выхода из канала. Также легко взглянуть на 7bitконтент и понять его. Идея здесь в том, что если вы просто пишете «обычным английским текстом», все будет в порядке. Но это было не так в 2005 году, и это неверно сегодня.

8-битное кодирование

8bitозначает: «Мои данные могут включать расширенные символы ASCII; они могут использовать 8-й (старший) бит для обозначения специальных символов, выходящих за рамки стандартных 7-битных символов US-ASCII». Как и в случае 7bit, по-прежнему существует ограничение в 1000 строк.

8bit, точно так же 7bit, на самом деле не выполняет никакого преобразования байтов, когда они записываются или читаются по сети. Это просто означает, что вы не гарантируете, что ни в одном из байтов старший бит не будет установлен в «1».

Это похоже на шаг вперед 7bit, так как это дает вам больше свободы в вашем контенте. Однако RFC 1341 содержит этот лакомый кусочек:

На момент публикации этого документа не существовало стандартизованных транспортных средств Интернета, для которых было бы законным включение некодированных 8-битных или двоичных данных в тела почты. Таким образом, нет никаких обстоятельств, при которых «8-битное» или «двоичное» кодирование передачи контента действительно является законным в Интернете.

RFC 1341 вышел более 20 лет назад. С тех пор мы получили 8-битные расширения MIME в RFC 6152 . Но даже в этом случае ограничения по строкам могут применяться:

Обратите внимание, что это расширение НЕ исключает возможность ограничения длины строки сервером SMTP; серверы могут реализовать это расширение, но тем не менее устанавливают ограничение на длину строки не менее 1000 октетов.

Двоичное кодирование

binaryто же самое 8bit, за исключением того, что нет ограничения на длину строки. Вы по-прежнему можете включать любые символы, и без дополнительной кодировки. Подобно 8bitRFC 1341, говорится, что это не совсем законная кодировка для передачи данных. RFC 3030 расширил это за счетBINARYMIME .

Цитата для печати

До 8BITMIMEрасширения должен был существовать способ отправки контента, который нельзя было передать 7bitчерез SMTP. HTML-файлы (которые могут содержать более 1000 строк) и файлы с международными символами являются хорошими примерами этого. quoted-printableКодирования (Определено в разделе 5.1 RFC 1341) предназначен для обработки этого. Он делает две вещи:

  • Определяет, как экранировать символы, отличные от US-ASCII, чтобы они могли быть представлены только 7-битными символами. (Краткая версия: они отображаются как знак равенства плюс два 7-битных символа.)
  • Определяет, что длина строк не превышает 76 символов, и что разрывы строк будут представлены с использованием специальных символов (которые затем экранируются).

Quoted Printable из-за экранирования и коротких строк гораздо труднее читать человеку, чем 7bitили 8bit, но он поддерживает гораздо более широкий диапазон возможного контента.

Кодировка Base64

Если ваши данные в основном нетекстовые (например, файл изображения), у вас не так много вариантов. 7bitвне стола. 8bitи binaryне поддерживались до RFC расширения MIME. quoted-printableбудет работать, но действительно неэффективно (каждый байт будет представлен 3 символами).

base64- хорошее решение для этого типа данных. Он кодирует 3 необработанных байта как 4 символа US-ASCII, что относительно эффективно. RFC 1341 дополнительно ограничивает длину строки base64закодированных данных до 76 символов, чтобы соответствовать SMTP-сообщению, но этим относительно легко управлять, когда вы просто разделяете или объединяете произвольные символы фиксированной длины.

Большим недостатком является то, что base64закодированные данные практически не читаются людьми, даже если это просто "простой" текст под ними.

Крейг Уокер
источник
10
Это потрясающий ответ, я бы хотел проголосовать 100 раз! Один вопрос: применяются ли эти правила для вложений? У меня есть пример XML-файла, прикрепленного к электронному письму, где содержимое XML-файла содержит данные UTF-8. Какой здесь правильный подход?
TrojanName
1
@TrojanName: Да, это относится ко всему содержимому электронной почты, включая вложения. (Все под крышками - это просто «части» MIME, но это уже другая история.) Вам все равно придется как-то закодировать свой контент, чтобы передать его в электронное письмо.
Craig Walker
1
@TrojanName: Любой файл является «двоичным» файлом, независимо от того, может ли он также рассматриваться как текст, поэтому доступны BINARYMIME и BINARY (насколько они доступны для чего угодно). 7Bit не подходит, так как вашему контенту UTF-8 требуется 8 бит для представления контента. 8Bit не годится, поскольку требует ограничений на длину строки, которые не являются частью вашего контента.
Craig Walker
2
Остается Quoted Printable или Base64, оба из которых могут успешно закодировать ваш XML-документ в вашу электронную почту. Обратите внимание, что оба из них усложнят чтение человеком в необработанном формате (Base64 не читается, QP сложно). Но удобочитаемость для человека - это второстепенная проблема; пока вы всегда предполагаете, что вам нужно не только кодировать, но и декодировать его, тогда все в порядке.
Craig Walker
2
Ограничения на добавление: 8-битные не должны включать нули, CR или LF без конца строки.
Макс