web-dev-qa-db-ja.com

なぜbase64が必要なのですか(別名、バイナリファイルをメールで送信できないのはなぜですか)。

私はBase64エンコーディングについて読んでいて、ウィキペディアでこれを見つけました:

Base64エンコードスキームは、テキストデータを処理するように設計されたメディアに保存および転送する必要があるバイナリデータをエンコードする必要がある場合に一般的に使用されます。

...そして与えられた例は、バイナリファイルを電子メールで送信することです。

なぜbase64が必要なのか理解しようとしています。バイナリデータはバイトの集まりなので、テキストデータであるASCIIに直接変換できませんか?なぜbase64が必要なのですか?または、EメールはASCIIの制御文字に問題がありますか?

31
Cookie Monster

これについては良い Wikipediaの記事 があります。


ARPAnetで使用されたNCPの最も初期の反復は、バイトストリームよりもビットストリームに似ていた、または便利なバイトサイズをネゴシエートしようとしたものでした。 8ビットバイトはかなり後に標準化されました。さまざまなマシンで機能するファイル転送プロトコルを作成する試みもいくつかありました(メールは最初は主に MAILおよびMLFL としてFTPプロトコルの機能でしたコマンド、次に [〜#〜] mtp [〜#〜] に分割し、後で [〜#〜] smtp [〜#〜] 。)に分割します。これらのマシンでは、多くの場合、異なる文字エンコーディング– ASCII vs EBCDIC –またはさらに異なるバイトサイズ、8ビットバイトvs 6ビットvs ...

したがって、メール転送機能は当初、比較的短いメッセージをプレーンテキストで転送するために定義されていました。具体的には、「NVT-ASCII」。たとえば、 RFC 772 は次のように述べています。

メールの提示と保管

メールは、送信ホストのストレージデバイスから受信ホストのストレージデバイスに転送されます。 2つのシステムのデータストレージ表現が異なるため、メールに対して特定の変換を実行する必要がある場合があります。たとえば、NVT-ASCIIは、さまざまなシステムでさまざまなデータストレージ表現を持っています。 PDP-10は通常、NVT-ASCIIを5つの7ビットとして保存しますASCII文字、36ビットワードで左揃え。360はNVT-ASCIIを32内の4つの8ビットEBCDICコードとして保存します。マルチビットはNVT-ASCIIを36ビットワードの4つの9ビット文字として格納します。

簡単にするために、すべてのデータはMTPではNVT-ASCIIとして表す必要があります。これは、送信ホストと受信ホストが異なるかどうかに関係なく、テキストを送信するときに文字を標準のNVT-ASCII表現に変換する必要があることを意味します。送信側は、データを内部の文字表現から標準の8ビットNVT-ASCII表現に変換します(TELNET仕様を参照)。受信側は、データを標準形式から独自の内部形式に変換します。この標準に従って、シーケンスはテキストの行の終わりを示すために使用されるべきです。

8ビットがネットワーク経由で送信されていたとしても、8番目のビットを保持する必要がないため、8番目のビットは破棄または破壊されることがよくありました。実際、一部のプロトコルが必要です8番目のビットをゼロに設定する必要があります。たとえば、以下に引用する初期の SMTP RFC などです。つまり、ソフトウェアは 8ビットクリーン ではありませんでした。

データ転送

TCP接続は8ビットバイトの送信をサポートしています。SMTPデータは7ビットですASCII文字。各文字は8ビットバイトとして送信されます上位ビットがゼロにクリアされます。

これは、8ビットのISO-8859-#文字エンコーディングが普及した後も、長い間続きました。一部のサーバーは既に8ビットクリーンでしたが、そうでないサーバーもあり、8ビットデータを盲目的に送信するとメッセージが破損します。

後で "Extended SMTP" が公開され、メールサーバーがサポートするSMTP拡張機能を宣言できるようになりました。それらの1つは 8BITMIME でした。これは、受信サーバーが8ビットデータを安全に受け入れることができることを示しています。 MIMEメッセージパーツには " Content-Transfer-Encoding :8bit"を含めることができます。これは、それらがどのようにもエンコードされていないことを示します。

ただし、SMTPプロトコルはラインベースのままで、998オクテットのライン制限があり、「メッセージの終わり」インジケータとして.ライン(0D 0A 2E 0D 0A)を使用しています。これは、ほとんどのバイナリファイルが変更されずに送信されても​​、このオクテットシーケンスを含むファイルが転送されたメッセージの終わりとして解釈され、残りのファイルがSMTPコマンドとして解釈され、損傷を引き起こす可能性があることを意味します。同様に、998オクテットより長い「回線」は、受信サーバーによって遮断される可能性があります。

2000年に、 "BINARYMIME" ESMTP拡張RFC 30 として公開され、生のバイナリデータをSMTP経由で転送できるようになりました。メッセージは、事前に指定された長さのチャンクで転送され、長さゼロのチャンクがターミネーターとして使用されます。Base64および同様のエンコードは不要になりました。残念ながら、いくつかのSMTPサーバーがこの拡張をサポートしています。たとえば、PostfixもExim4もEHLOに応答してCHUNKINGをアドバタイズしません。 BINARYMIMEを利用するには、メッセージパス内のallサーバーでサポートされている必要があります。

以下も参照してください。

38
user1686

一部の古い電子メールシステムとソフトウェアは 8ビットクリーン ではなく、8番目のビットが制御文字として使用されていました。これはバイナリファイルをマックアップするのに十分だったので、Base64(または他のエンコーディングスキーム)が必要でした。

7
Renan