Кодировка темы японской электронной почты

По-видимому, кодирование японских писем несколько сложнее, и я медленно обнаруживаю себя. В случае, если есть какие-либо эксперты (даже те, у кого ограниченный опыт, будут делать), могу ли я получить некоторые рекомендации относительно того, как это сделать, как проверить его и как его проверить?

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

Что (я думаю), я знаю до сих пор следующее:
- Японские электронные письма должны быть закодированы в ISO-2022-JP, японской кодировке 50220 JIS или, возможно, кодовой странице SHIFT_JIS 932
- Кодировка передачи электронной почты должна быть установлена ​​на Base64 для обычного текста и 7Bit для Html
- Тема электронной почты должна кодироваться отдельно, чтобы начать с "=? ISO-2022-JP? B?" (не знаю, что это означает). Я пробовал кодировать тему с помощью

"=?ISO-2022-JP?B?" + Convert.ToBase64String(Encoding.Unicode.GetBytes(subject))

который в основном дает закодированную строку, как ожидалось, но она не может быть представлена ​​как любой японский текст в программе электронной почты
- Я тестировал в Outlook 2003, Outlook Express и GMail

Любая помощь будет принята с благодарностью


Итак, чтобы опубликовать короткое обновление, благодаря двум полезным ответам, мне удалось получить нужный формат и кодировку. Теперь Outlook дает что-то похожее на правильный предмет:
=?iso-2022-jp?B?6 Japanese test に各々の視点で語ってもらった。 6相当の防水?=

Однако, то же самое электронное письмо в Outlook Express дает такую ​​тему:
=?iso-2022-jp?B?6 Japanese test 縺ォ蜷・・・隕也せ縺ァ隱槭▲縺ヲ繧ゅi縺」縺溘・ 6逶ク蠖薙・髦イ豌エ?=

Кроме того, при просмотре в представлении "Входящие" в Outlook Express тема электронной почты еще более странная: =?iso-2022-jp?B?6 Japanese test ??????????????? 6???????=

Кажется, что Gmail работает аналогично Outlook, что выглядит правильно.

Я просто не могу обойти эту тему.

Ответы

Ответ 1

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

  • Прежде всего, не используйте Shift-JIS. Я лично получаю тонны японских электронных писем и почти никогда не кодируется с помощью Shift-JIS. Я думаю, что старая (около Win 98?) Версия Outlook Express кодировала исходящую почту с использованием Shift-JIS, но в настоящее время вы ее просто не видите.

  • Как вы поняли, вам нужно использовать ISO-2022-JP в качестве кодировки, по крайней мере, для всего, что входит в почтовый заголовок. Сюда входят линия Subject, To и CC. UTF-8 также будет работать в большинстве случаев, но он не будет работать на почте Yahoo Japan, и, как вы можете себе представить, многие японские пользователи используют почту Yahoo Japan.

  • Вы можете использовать UTF-8 в теле письма, но рекомендуется, чтобы base64 кодировал кодированный японским текстом UTF-8 и помещал его в тело вместо необработанного текста UTF-8. Однако на практике я считаю, что сырой текст UTF-8 будет отлично работать в эти дни, для тела письма.

  • Как я уже упоминал выше, вам нужно, по крайней мере, проверить почту Outlook (Exchange), Outlook Express (IMAP/POP3) и Yahoo Japan. Yahoo Japan является самым сложным, потому что я считаю, что они используют EUC для кодирования своих веб-страниц, поэтому вам нужно следовать правильным стандартам для ваших электронных писем или они не будут работать (ISO-2022-JP является стандартом для отправки японских электронных писем).

  • Кроме того, ваша строка темы не должна превышать 75 символов в строке. То есть, 75 символов после кодирования в ISO-2022-JP и base64, а не до 75 символов перед преобразованием. Если вы превысите 75 символов, вам нужно разбить закодированный объект на несколько строк, начиная с "=? Iso-2022-jp? B?" и заканчивая "? =" на каждой строке. Если вы этого не сделаете, ваш субъект может быть усечен (в зависимости от чтения электронной почты, а также от содержания вашего текста темы). Согласно RFC 2047:

"закодированное слово" может содержать не более 75 символов, включая "кодировку", "кодировку", "кодированный текст" и разделители. Если желательно кодировать больше текста, чем вписывается в "закодированное слово" из 75 символов, может использоваться несколько "закодированных слов" (разделенных пространством CRLF).

  • Вот пример кода PHP для кодирования темы:

 // Convert Japanese subject to ISO-2022-JP (JIS is essentially ISO-2022-JP)

 $subject = mb_convert_encoding ($subject, "JIS", "SJIS");

 // Now, base64 encode the subject

 $subject = base64_encode ($subject);

 // Add the encoding markers to the subject

 $subject = "=?iso-2022-jp?B?" . $subject . "?=";

 // Now, $subject can be placed as-is into the raw mail header.
  • См. RFC 2047 для полного описания того, как закодировать свой заголовок электронной почты.

Ответ 2

Отметьте http://en.wikipedia.org/wiki/MIME#Encoded-Word описание того, как закодировать поля заголовка в сообщениях, совместимых с MIME. Кажется, у вас отсутствует "? =" В конце вашего вопроса.

Ответ 3

=? ISO-2022-JP? B? TEXTTEXT...

ISO_2022-JP означает, что строка кодируется в кодировке ISO-2022-JP (например, не в Юникоде) B означает, что строка кодируется bese64

В вашем примере вы должны просто указать свою строку в ISO-2022-JP вместо Unicode.

Ответ 4

У меня есть опыт составления и отправки электронной почты на японском языке... Обычно вам нужно остерегаться, какая кодировка используется для операционной системы и как вы храните свои японские строки! Мои объекты Mail обычно кодируются следующим образом:

    string s = "V‚µ‚¢ŠwK–@‚Ì‚²’ñˆÄ"; // Our japanese are shift-jis encoded, so it appears like garbled
    MailMessage message = new MailMessage();
    message.BodyEncoding = Encoding.GetEncoding("iso-2022-jp");
    message.SubjectEncoding = Encoding.GetEncoding("iso-2022-jp");
    message.Subject = s.ToEncoding(Encoding.GetEncoding("Shift-Jis")); // Change the encoding to whatever your source is
    message.Body = s.ToEncoding(Encoding.GetEncoding("Shift-Jis")); // Change the encoding to whatever your source is

Тогда у меня есть метод расширения, для которого выполняется преобразование для меня:

public static string ToEncoding(this string s, Encoding targetEncoding)
        {   
            return s == null ? null : targetEncoding.GetString(Encoding.GetEncoding(1252).GetBytes(s)); //1252 is the windows OS codepage            
        }

Ответ 5

что-то вроде этого должно выполняться в python:


#!/usr/bin/python                                                                                                            
# -*- mode: python; coding: utf-8 -*-                                                                                        
import smtplib
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate

def send_from_gmail( from_addr, to_addr, subject, body, password, encoding="iso-2022-jp" ):

    msg = MIMEText(body.encode(encoding), 'plain', encoding)
    msg['Subject'] = Header(subject.encode(encoding), encoding)
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Date'] = formatdate()

    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.ehlo(); s.starttls(); s.ehlo()

    s.login(from_addr, password)
    s.sendmail(from_addr, to_addr, msg.as_string())
    s.close()
    return "Sent mail to: %s" % to_addr



if __name__ == "__main__":
    import sys
    for n,item in enumerate(sys.argv):
        sys.argv[n] = sys.argv[n].decode("utf8")

    if len(sys.argv)==6:
        print send_from_gmail( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] )
    elif len(sys.argv)==7:
        print send_from_gmail( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], encoding=sys.argv[6] )
    else:
        raise "SYNTAX: %s <from_addr> <to_addr> <subject> <body> <password> [encoding]"

**, явно украденный/адаптированный из:

http://mtokyo.blog9.fc2.com/blog-entry-127.html

Ответ 6

Прежде всего, вы должны использовать:

Encoding.GetEncoding("ISO-2022-JP")

чтобы преобразовать строку темы в байты, которые будут обрабатываться Convert.ToBase64String().

=? ISO-2022-JP? B? TEXTTEXT...? = сообщает получающему почтовому клиенту, какая кодировка использовалась на стороне отправителя, чтобы преобразовать японские буквы в поток байтов.

В настоящее время вы используете кодировку UTF-16, но указываете ISO-2022-JP для декодирования. Очевидно, что это два разных кодирования, как и в ISO-8859-1, отличается от Unicode (наиболее распространенные символы западного европы представлены одним байтом в ISO-XXX, но два байта в Юникоде).

Я не уверен, что вы имеете в виду, что UTF-8 является гражданином второго сорта. Пока получающий почтовый клиент понимает UTF-8 и способен преобразовать его в текущую японскую локаль, все в порядке.

Ответ 7

<?php

function sendMail($to, $subject, $body, $from_email,$from_name)
 {
$headers  = "MIME-Version: 1.0 \n" ;
$headers .= "From: " .
       "".mb_encode_mimeheader (mb_convert_encoding($from_name,"ISO-2022-JP","AUTO")) ."" .
       "<".$from_email."> \n";
$headers .= "Reply-To: " .
       "".mb_encode_mimeheader (mb_convert_encoding($from_name,"ISO-2022-JP","AUTO")) ."" .
       "<".$from_email."> \n";


$headers .= "Content-Type: text/plain;charset=ISO-2022-JP \n";


/* Convert body to same encoding as stated
in Content-Type header above */

$body = mb_convert_encoding($body, "ISO-2022-JP","AUTO");

/* Mail, optional parameters. */
$sendmail_params  = "-f$from_email";

mb_language("ja");
$subject = mb_convert_encoding($subject, "ISO-2022-JP","AUTO");
$subject = mb_encode_mimeheader($subject);

$result = mail($to, $subject, $body, $headers, $sendmail_params);

return $result;
}

Ответ 8

Введение японской кодировки в электронную почту происходило в JUNET (основанная на UUCP общенациональная сеть) в начале 90-х годов.

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

Если вы хотите обрабатывать html-почту, RFC1468 бесполезен, за исключением частей заголовка.

Ответ 9

Вот что я использую для отправки японских писем. Строка темы отлично выглядит в Outlook 2010, gmail и на iPhone.

Encoding encoding = Encoding.GetEncoding("iso-2022-jp");
byte[] bytes  = encoding.GetBytes(subject);
string uuEncoded = Convert.ToBase64String(bytes);
subject = "=?iso-2022-jp?B?" + uuEncoded + "?=";

// not sure this is actually necessary...
mailMessage.SubjectEncoding = Encoding.GetEncoding("iso-2022-jp");