Кодировка UTF-8 в электронных письмах, разбор тела - PullRequest
0 голосов
/ 24 апреля 2020

Так что я не хочу, чтобы этот вопрос задавался языком c, однако я подозреваю, что здесь играет роль Go (мой выбор языка). Я пытаюсь найти строку в теле сырой электронной почты. Для этого я получаю кодировку, и большинство дел составляют quoted-printable. Хорошо, так что все в порядке, я кодирую свой поисковый запрос, цитируемый для печати, а затем выполняю поиск. Это работает. Однако. В одном конкретном c случае сырая электронная почта, которую я вижу в gmail, выглядит нормально, однако, когда я получаю сырую электронную почту из API gmail, хотя кодировка и все идентичные, она кодирует " как =22 Исследования показывают, что я это потому, что кодировка utf-8. Я не совсем понял, кодирует ли это тот кодировщик utf-8, который затем цитируется-печатается, или наоборот, но это тоже не совсем вопрос .... Если я посмотрю на электронное письмо, где " равно =22 Я вижу набор символов utf-8, и когда я смотрю на другой, где он не закодирован, кодировка UTF-8 (обратите внимание на случай). Я не могу поверить, что дело в том, что именно здесь и происходит, но это не выглядит достаточно надежным способом, если =22 на самом деле =22 или является " в кодировке utf-8.

Моя первоначальная мысль состояла в том, чтобы всегда декодировать цитируемую печатную форму и затем перекодировать ее перед выполнением поиска, но я не думаю, что это будет надежный подход в будущем, и я подумал, что у других может быть лучшее предложение ?

Заключение, я пытаюсь найти строку в необработанном электронном письме, но кодировка вызывает у меня проблемы с получением моей строки поиска, совпадающей с кодировкой тела

1 Ответ

0 голосов
/ 27 апреля 2020

Кодировка =22 на самом деле не имеет ничего общего с кодировкой (будь то строчная UTF-8, прописная UTF-8 или любая другая кодировка).

Это кодировка Content-Transfer-Encoding: quoted-printable .

Кодировка для печати в кавычках - это просто способ октетов шестнадцатеричного кодирования, обычно ограниченный октетами, выходящими за пределы диапазона ascii для печати. Кажется странным, что символ DQUOTE будет закодирован таким образом, но это совершенно законно.

Если вы хотите искать строки в теле сообщения, вам необходимо сначала декодировать Тело сообщения. В противном случае вы не добьетесь успеха.

Я бы порекомендовал прочитать rfc2045 как минимум.

Возможно, вам также понадобится прочитать rfc2047 , если вы в конечном итоге захотите поискать заголовки в какой-то момент, но это становится ... хитрым из-за различных ошибок, которые имеют отправляющие клиенты.

Теперь, когда меня "вызвали" в разглагольствования по поводу MIME, позвольте мне Объясните, почему декодирование заголовков так сложно сделать правильно. Я уверен, что почти каждый разработчик, который когда-либо работал над почтовым клиентом, мог бы сказать вам об этом, но я думаю, что я буду тем, кто сделает это.

Вот лишь краткий список проблем каждый разработчик сталкивается, когда он go должен реализовать декодер для заголовков, которые (теоретически) были закодированы в соответствии со спецификацией rfc2047:

  1. Во-первых, технически существует два варианта кодирования заголовка форматы, определенные rfc2047 - один для фраз и один для неструктурированных текстовых полей. Они очень похожи, но вы не можете использовать одни и те же правила для их токенизации. Я упоминаю об этом, потому что кажется, что большинство парсеров MIME пропускают это очень тонкое различие и, как вы можете себе представить, делают большинство генераторов MIME. Черт, большинство генераторов MIME, вероятно, даже никогда не слышали о спецификациях, для начала это кажется.

    Это подводит нас к следующему:

  2. Существует множество вариантов сбоя заголовков MIME. быть токенизируемым в соответствии с правилами rfc2822 и rfc2047. Вы встретите забавные вещи, такие как:

    a. токены кодированных слов, незаконно встраиваемые в токены других слов

    b. токены закодированных слов, содержащие в себе недопустимые символы (такие как пробелы, разрывы строк и т. д.), эффективно позволяющие токенайзеру больше не использовать токены (по крайней мере, нелегко)

    c , Последовательности многобайтовых символов разделены между несколькими токенами кодированных слов, что означает, что невозможно декодировать указанные токены кодированных слов по отдельности

    d. полезные нагрузки токенов кодированных слов разбиваются на несколько токенов кодированных слов, часто разделяясь в месте, которое делает невозможным декодирование полезных данных изолированно

    Вы можете увидеть некоторые примеры здесь .

  3. Многие разработчики, по-видимому, упускают из виду тот факт, что каждому токену закодированного слова разрешено быть в различных кодировках символов (у вас может быть один токен в UTF-8, другой в ISO-8859-1 и еще один в koi8-r). Обычно это не представляет особой проблемы, поскольку вы просто декодируете каждую полезную нагрузку, а затем конвертируете из указанной кодировки в UTF-8 с помощью iconv () или чего-то еще. Однако из-за забавного нарушения, о котором я упоминал выше в (2 c) и (2d), это становится более сложным.

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

  4. Необъявленный 8-битный текст в заголовках. Ага. Некоторые почтовые программы просто не получили памятку о том, что они должны кодировать текст не ASCII. Так что теперь у вас есть забавный опыт смешивания и сопоставления необъявленного 8-битного текста «только Бог знает, что такое кодировка» вместе с содержанием (возможно, битых) закодированных слов.

Если вы хотите узнать, как справиться с этими проблемами, вы можете посмотреть, как я это сделал, используя C в моей библиотеке GMime , здесь: https://github.com/jstedfast/gmime/blob/master/gmime/gmime-utils.c#L1894 (в случае, если смещения линий изменятся в будущем, найдите _g_mime_utils_header_decode_text() и различные внутренние методы, которые он использует в этом исходном файле - я написал комментарии, объясняющие, как он справляется с вышеуказанными проблемами).

Или вы посмотреть, как я это сделал, используя C# в моей библиотеке MimeKit , можно здесь: https://github.com/jstedfast/MimeKit/blob/master/MimeKit/Utils/Rfc2047.cs

Для получения дополнительной информации о том, почему и как трудно работать с электронной почтой Посмотрите блог серии Джошуа Крамнера: http://quetzalcoatal.blogspot.com/search/label/email-hard

...