3 ポイント 投稿者 GN⁺ 2026-02-04 | 1件のコメント | WhatsAppで共有
  • 最近Twitterで古いメールの引用文が広まり、文末の イコール記号(=) がなぜ現れるのかという疑問が提起された
  • この記号は quoted-printable エンコーディング の過程で生じるもので、長い行を強制的に分割するときに行が続くことを示すために使われる
  • メール送信時には CRLF(キャリッジリターン+ラインフィード) を改行として使うが、これを Unix の NL に変換する際にデコードアルゴリズムが誤作動すると、イコール記号が残ったり文字が失われたりする
  • イコール記号は改行以外にも 非ASCII文字(例: =C2=A0) を表すために使われ、誤ったデコーダがこれを単純置換するとエラーを引き起こす
  • 問題の原因は バグのあるデコードロジックと不適切な変換処理 にあり、メールを加工した人が技術的に未熟だったことを示している

メール引用文中のイコール記号(=)の正体

  • ここ数日、Twitterで 古いメールの引用文 が多数共有され、文末のイコール記号が目立つ現象が発生

    • 筆者は、これを コードやOCR(光学文字認識)の誤り だと誤解する主張に反論
    • 実際には、メールを読みやすく変換する過程で生じた エンコーディング処理のエラー である
  • メールは以前は単純なテキストだったが、長い行や特殊文字を扱うために quoted-printable エンコーディング が導入された

    • 長い行を分割するとき、行末にイコール記号(=)を付けて「この行は続く」という意味を示す
    • このとき、イコール記号の後には CRLF(キャリッジリターン+ラインフィード) が付く

改行エンコーディングとデコードエラー

  • メールサーバーは CRLF 改行を標準として使うが、Unix 系システムは NL だけを使う

    • 変換過程で1バイト減り、デコーダがこれを誤って処理するとイコール記号が残ったり文字が抜け落ちたりする
    • 例として、「non- =CRLF cloven」が誤って処理されると「non- loven」のように c が消える
  • 一部の実装は、行末のイコール記号を見つけると2文字を削除する方式で処理する

    • このアルゴリズムが Unix 形式のファイルでは誤作動し、イコール記号がそのまま残る現象が起きる

イコール記号のもう一つの用途: 非ASCII文字エンコーディング

  • イコール記号は改行以外にも 非ASCII文字エンコーディング に使われる

    • 例: =C2=A0non-breaking space(改行しない空白) を意味する
    • メール本文でインデントや特殊文字の表現時によく現れる
  • 筆者は、一部の変換処理が =C2, =A0 などを単純な置換(search-replace)だけで処理し、正しいデコーダを使わなかった と推測している

技術的背景と標準

  • RFC 2045 標準は quoted-printable エンコーディングを 転送用(transport) と定義している

    • 受信後はデコードされて きれいなテキスト として保存されるのが原則
    • しかし実際の実装ではこの工程が省略され、改行処理のエラーが頻発する
  • 例示コードの (quoted-printable-decode-string "he=\nllo")"hello" に正常復元される

    • これは SMTP サーバーの文脈で CRLF を前提としたアルゴリズムを再利用しているため
    • Windows ベースのファイルでは正常に動作するが、Unix ベースでは失敗する

結論

  • メール引用文中のイコール記号は quoted-printable エンコーディングの残骸 であり、
    改行処理と非ASCII文字デコードの欠陥 が組み合わさった結果である
  • 問題の根本原因は 不正確なデコーダ実装とエンコーディング変換ミス にある
  • 筆者はこれを「技術的な問題であり、誤った処理の結果」だと要約し、
    メール変換過程で標準を細かく順守する必要性を強調している

1件のコメント

 
GN⁺ 2026-02-04
Hacker Newsのコメント
  • この記事の中心人物は Lars Ingebrigtsen で、Emacs のメール/Usenet リーダーパッケージである Gnus のマニュアルを書いた人物とのこと
    彼のマニュアルは機知に富み有益で、メールのパースについて大半の人よりはるかに深い理解を持っている
    マニュアルはこちらで読め、別バージョンはこのリンクにある

    • 彼はマニュアルだけでなく、Gnus 自体の開発者でもある
      UiO(オスロ大学)で彼が最初に Gnus を作っていた頃を覚えているという話
      情報学科の学生たちの間ではちょっとした スター開発者 で、みんな Emacs と Gnus を使っていた
  • これは「危険なほど知っている人」の典型例だという意見
    メールが単なるプレーンテキストではないことは知っていたが、quoted-printable のデコードを単純な置換で処理してはいけないことまでは知らなかった、という話
    正規表現で HTML を直接パースするバグと同類で、最初はうまくいっているように見えるが、あとで 議会の証拠資料に ‘=’ 記号が大量に残る 事態になる

    • これに関連して有名な Stack Overflow の回答 が共有されている。HTML を正規表現でパースしてはいけない理由をユーモラスに説明している
    • 出力はだいたい読めてしまうので、誰も問題に気づかず、何年も後に議会証拠として提出される段階でようやく発覚する
    • 「現在、最高の人材が対応中です」というジョークで締めている
  • 「メールサーバはなぜ長い行を嫌うのか」という質問があった

    • SMTP は 行ベースのプロトコル なので、メッセージ本文も行単位で送信される
      サーバはヘッダをパースする必要があるため、単純なバイナリ blob として扱えない
      IMAP はサーバ側で完全なパースが必要で、POP3 は単一デバイス向けなので今では合わない
    • 昔はメールを固定長バッファで行単位に処理していた
      RFC 821 は行長を最大 1000 バイトに制限しており、互換性のため 80 文字以下で区切るのが一般的だった
      そのため Base64 エンコードにも 76 文字ごとに改行 が入る
    • SMTP が設計された当時はメモリが極端に限られていた
      たとえば PDP-11 は 512KB、VAX-11 は 2MB 程度で、プログラマたちは バイト単位でメモリを計算 していた
    • SMTP のコマンドフローを直接示し、HELO, MAIL FROM, RCPT TO, DATA などで通信する構造を説明している
    • 1980年代の大学ネットワーク BITNET にも触れ、当時も行長制限があったことを回想している
      関連文書は IBM 公式ドキュメントWikipedia で見られる
  • 最初はこの記事が = == === .=. <== ==> <<== ==>> (==) => =~= のような 演算子の意味 の話かと思った、というコメント

    • 「これはアリ向けの Haskell か?」というジョークが付いていた
    • だが実際の内容はその予想よりずっと面白かったという
  • 個人的にメールアーカイブ用ソフトウェアを自作したことがあるという人もいた
    20年以上蓄積された .eml ファイルの エッジケース処理 がいちばん難しかった
    概念は単純でも、メールは驚くほど複雑だという

    • メール標準は最初から作り直されたものではなく、既存システムを無理やりつなぎ合わせてできた 呪われた標準 だという指摘
      メールアドレスの妥当性検証も、実質的には不可能に近い
    • コンソールベースのメールクライアントを作ったが、25% は C++、75% は Lua で UI と処理を定義していた
      数年間少数のユーザーはいたものの、MIME 処理 が最大の苦痛だった
  • 興味深かったのは ‘=’ 記号そのものより、その周辺の 文字が消える現象 だったという意見
    off-by-one エラーのように、‘=’ を消す代わりに実際のテキストの一部が失われたように見える
    おそらく CRLF/LF 変換が関係しているのではないかという

    • 元記事ではその理由を正確に説明している
    • こうして 証拠資料から文字が消えるミステリー が生まれる
  • なぜこうした問題が 今になって 表面化しているのか気になった、というコメント
    ここ数日、人々が古いメールを Twitter に投稿しているが、何が理由なのかと思っていたという

    • おそらく Epstein 関連メールの公開 が理由ではないかとのこと
    • 実際に DOJ が Epstein のメールを追加公開したという
  • 原因は Gmail ではなく 中間サーバでの変換 の可能性がある、という指摘もあった
    CRLF→LF 変換に加え、quoted-printable を二重適用すると ‘=’ が残る現象が起こるため、2台のメールサーバが関与していた可能性がある

    • 一部の PDF には Apple Mail.app の plist メタデータ が見えており、内部フォーマットから抽出された可能性がある
    • 法的証拠の収集過程ではこうしたことがよく起きる
      実際には 非専門のインターン が単純なツールでデータを集め、何度も変換されるうちにフォーマットが壊れる
      元データはすでに破棄され、残るのは 形だけ残った断片データ だけになる
    • メールを MS Outlook の PST ファイルにインポート する過程でこうした問題が起こることもある
    • 単一の Gmail ダンプではなく、複数のシステムが「助けようとして」データを変形した結果物のようだ
    • この仮説がもっとも説得力があるという意見もあった
  • archive.today の記事にも同じ quoted-printable の破損現象 が見られる
    関連リンクは pastes.io/correspondHN スレッド

  • Outlook でダウンロードしたメールを見る際、quoted-printable を自動でデコードしてくれる .eml ビューア があるとよい、とのこと