145

base64 エンコーディングでのパディングの目的は何ですか。以下はウィキペディアからの抜粋です。

「追加の埋め込み文字が割り当てられ、エンコードされた出力を 4 文字の整数倍に強制するために使用できます (または、エンコードされていないバイナリ テキストが 3 バイトの倍数でない場合も同様です)。これらの埋め込み文字は、デコード時に破棄する必要がありますが、入力バイナリ長が 3 バイトの倍数でない場合、エンコードされていないテキストの有効長の計算を引き続き許可します (最後の非埋め込み文字は通常、それが表す最後の 6 ビット ブロックがゼロになるようにエンコードされます)。 -最下位ビットにパディングされ、エンコードされたストリームの最後に最大 2 つのパディング文字が発生する可能性があります)。

任意の文字列を base64 でエンコードし、base64 でエンコードされた任意の文字列をデコードできるプログラムを作成しました。パディングはどのような問題を解決しますか?

4

4 に答える 4

53

関連するメモとして、私が作成した任意の基本コンバーターを次に示します。楽しみ! https://convert.zamicol.com/

パディング文字とは

パディング文字は、長さの要件を満たすのに役立ちますが、意味を持ちません。

パディングの 10 進数の例: すべての文字列の長さが 8 文字であるという任意の要件を考えると、数値 640 は、意味を持たないため、前の 0 をパディング文字として使用してこの要件を満たすことができます (「00000640」)。

バイナリ エンコーディング

バイト パラダイム:バイトは事実上の標準的な測定単位であり、エンコード方式はすべてバイトに関連付ける必要があります。

Base256はまさにこのパラダイムに適合します。1 バイトは base256 の 1 文字に相当します。

Base16、16 進数または 16 進数は、各文字に 4 ビットを使用します。1 バイトで 2 つの base16 文字を表すことができます。

base64 は、base256 やbase16とは異なり、バイト パラダイムに均等に適合しません (base32 も適合しません)。すべての base64 文字は、フルバイトより 2 ビット短い 6 ビットで表すことができます。

base64 エンコーディングとバイト パラダイムを分数として表すことができます: 1 文字あたり 6 ビット、1 バイトあたり 8 ビット。この部分を減らすと、4 文字で 3 バイトになります。

base64 文字を 4 文字ごとに 3 バイトというこの比率は、base64 をエンコードするときに従うべきルールです。 Base64 エンコーディングは、すべてのバイトが独立している base16 や base256 とは異なり、3 バイトのバンドルで測定することさえ約束できます。

では、パディング文字がなくてもエンコーディングは問題なく機能するにもかかわらず、パディングが推奨されるのはなぜでしょうか?

ストリームの長さが不明な場合、またはデータ ストリームがいつ終了するかを正確に知ることが役立つ場合は、パディングを使用します。パディング文字は、それらの余分なスポットを空にする必要があることを明示的に伝え、あいまいさを排除します。パディングで長さが不明な場合でも、データ ストリームがどこで終了するかがわかります。

反例として、JOSEなどの一部の標準ではパディング文字が許可されていません。この場合、何か不足していると、暗号化署名が機能しないか、他の非 base64 文字 (「.」など) が欠落します。長さについての仮定は行われていませんが、パディングは必要ありません。

そして、これはまさにbase64 RFC が述べていることです。

状況によっては、ベース エンコードされたデータでパディング ("=") を使用する必要がないか、または使用されません。一般に、転送されたデータのサイズに関する仮定を行うことができない場合、正しいデコードされたデータを生成するためにパディングが必要です。

[...]

Base 64 のパディング ステップ [...] 不適切に実装された場合、エンコードされたデータの重要でない変更につながります。たとえば、入力が base 64 エンコーディングの 1 オクテットのみの場合、最初のシンボルの 6 ビットすべてが使用されますが、次のシンボルの最初の 2 ビットのみが使用されます。これらのパディング ビットは、以下のパディングの説明で説明されているエンコーダを適合させることによってゼロに設定する必要があります。このプロパティが保持されない場合、ベースでエンコードされたデータの標準的な表現はなく、複数のベースでエンコードされた文字列を同じバイナリ データにデコードできます。このプロパティ (およびこのドキュメントで説明するその他のプロパティ) が保持される場合、正規のエンコーディングが保証されます。

パディングにより、失われたビットがないという約束で base64 エンコーディングをデコードできます。パディングがないと、3 バイト バンドルでの測定の明示的な確認がなくなります。パディングがないと、TCP、チェックサム、またはその他の方法など、通常はスタック内の別の場所から追加情報がなければ、元のエンコーディングの正確な再現を保証できない場合があります。

RFC 4648 の例を次に示します ( https://www.rfc-editor.org/rfc/rfc4648#section-8 )

「BASE64」関数内の各文字は、1 バイト (base256) を使用します。それを base64 に変換します。

BASE64("")       = ""           (No bytes used. 0%3=0.)
BASE64("f")      = "Zg=="       (One byte used. 1%3=1.)
BASE64("fo")     = "Zm8="       (Two bytes. 2%3=2.)
BASE64("foo")    = "Zm9v"       (Three bytes. 3%3=0.)
BASE64("foob")   = "Zm9vYg=="   (Four bytes. 4%3=1.)
BASE64("fooba")  = "Zm9vYmE="   (Five bytes. 5%3=2.)
BASE64("foobar") = "Zm9vYmFy"   (Six bytes. 6%3=0.)

これは、試してみることができるエンコーダーです: http://www.motobit.com/util/base64-decoder-encoder.asp

于 2013-08-29T18:36:19.763 に答える
8

現代ではあまりメリットはありません。それで、これを元の歴史的目的が何であったかという問題として見てみましょう。

Base64エンコーディングは、 1993年のRFC 1421で最初に登場しました。このRFCは、実際には電子メールの暗号化に焦点を当てており、base64は1つの小さなセクション4.3.2.4で説明されています。

このRFCは、パディングの目的を説明していません。元の目的について言及するのに最も近いのは、次の文です。

フルエンコーディングクォンタムは、常にメッセージの最後に完了します。

これは、連結(ここでのトップアンサー)や、パディングの明示的な目的としての実装の容易さを示唆するものではありません。ただし、説明全体を考慮すると、これがデコーダーが32ビット単位(「クォンタム」)で入力を読み取るのを支援することを目的としている可能性があると考えるのは不合理ではありません。これは今日では何のメリットもありませんが、1993年には、安全でないCコードが実際にこのプロパティを利用していた可能性が非常に高くなります。

于 2011-03-21T11:01:00.877 に答える