LoginSignup
33
27

More than 5 years have passed since last update.

メールのデコード処理の流れ

Last updated at Posted at 2018-08-28

メール本文のデコード処理の流れ

受信したメールのメッセージには、Content-Transfer-EncodingヘッダとContent-typeヘッダが記載されています。
デコード処理の流れとしては、まずContent-Transfer-Encodingヘッダを見てデコードし、次にContent-typeヘッダのcharsetを見て更にデコードします。

Content-Transfer-Encodingの種類

  • base64
  • quoted-printable
  • その他(7bit, 8bit, binary)

早い話、base64とquoted-printableの場合のみそれぞれの方式でデコードし、その他の場合は何もしなくて良いです。

charsetの種類

  • iso-2022-jp
  • utf-8
  • その他

iso-2022-jpとutf-8の場合はそれぞれの方式でデコードします。その他と書きましたが、例えば中国のフリーメールとか使うとISO-8859-1とかあります。
charsetが無い場合もあるようです。その場合、メール body部に使用されている文字コードを推測して変換するなどの対応が必要です。
以下の例ではその他を適当にasciiでデコードしています。

コード例

以上の流れをpythonで書くと、次のようになります。

def decode_msg(msg, cte, charset):
    """ メール本文をデコードする
    * msg
      - メール本文(バイナリ形式)
    * cte(Content-Transfer-Encoding)
      - "base64"
      - "quoted-printable"
      - それ以外は、そのまま
    * charset(文字コード)
      - "utf-8"
      - "iso-2022-jp"
      - それ以外は、"ascii"とみなす
    """
    import quopri
    import base64

    if cte == "base64":
        b = base64.b64decode(msg)
    elif cte == "quoted-printable":
        b = quopri.decodestring(msg, header=False)
    else:
        b = msg
    if charset == "iso-2022-jp":
        return b.decode("iso-2022-jp", "ignore")
    elif charset == "utf-8":
        return b.decode("utf-8", "ignore")
    else:
        return b.decode("ascii", "ignore")

SubjectヘッダやFromヘッダのデコード処理の流れ

Subjectヘッダ(件名)やFromヘッダ(送信元)は本文とは別でエンコーディングされています。どのような形で送られてくるかというと、

?[文字コード]?[Content-Transfer-Encoding]?[メッセージ]

という形になっています(基本は)。
結構ややこしく、例を以下に列挙します。

文字コードがUTF-8で、Base64変換されている場合

b"From: =?UTF-8?B?44CQQVdTIOOCp...?="

文字コードがiso-2022-jpで、Base64変換されている場合

b"From: =?iso-2022-jp?B?GyRCMlRG...?="

文字コードがUTF-8で、quoted-printable変換されている場合

b"Subject: =?UTF-8?Q?=E3=80=90=E3=83=A4=E3=..."

ただのバイナリ(ascii)

b"From: "tanaka@example.com" <yamada@example.com>"

文字コードがiso-2022-jpで、Base64変換されているが、2つ目の送信元はただのバイナリ

b"From: =?iso-2022-jp?B?GyRCPF...==?= <tanaka@example.com>"

複数行に跨っている(folding)

b"From: =?iso-2022-jp?B?GyRCQmdOUxsGyhCTktFGyRCM3Q8MDJxGyhC...?=
=?iso-2022-jp?B?GyRCPFIhQg...==?= <tanaka@example.com>"

全てに対応させるには気合が必要です。
と思ったら、Linuxコマンドで一撃でデコードできるっぽいです。
https://qiita.com/sheepland/items/2065ffcc7ec8c03145cc

備考

日本ではiso-2022-jp(JIS)がいまだに根強く使われています(大手新聞社やIT企業のメールでも使われています)。調べた感じ、ガラケーがまだ現役だからが主な理由のようです。

果たして自分がメールを送信するときにiso-2022-jpを選ぶかUTF-8を選ぶか悩みどころですが、ガラケーを気にしないのであればUTF-8で良いと思います。

33
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
27