Base64で変換して間違った文字を返すと、文字列の末尾に無効な文字が表示されるのはなぜですか?

Base64で変換して間違った文字を返すと、文字列の末尾に無効な文字が表示されるのはなぜですか?

注文する:

echo "HelloWorld==" | base64 -d | base64

出力:

HelloWorlQ==

私はなぜd今あるかQ

編集する:

任意のデータで始まり、Base64でエンコードしたくありません。私の目標は、Base64で始まりBase64で終わり、この間にバイナリ値のみを生成することです。

編集2:

入力文字列が4文字の倍数の場合、これは起こらないことがわかったので、パディングとの相互作用だと思います。

❯ echo 'abcdefghij==' | base64 -d | base64
abcdefghig==

❯ echo 'abcdefgh' | base64 -d | base64 
abcdefgh

編集3

-i私の問題とは無関係であることが判明した混乱したロゴの言及を削除しました。

答え1

HelloWorld==デコードできず、通常0パディングする必要があるため、技術的に有効なBase64以外の情報が含まれています。 .を使用すると、1その中に含まれる追加のsは無視され失われますecho "HelloWorld==" | base64 -d

説明する...

Base64は4文字のグループで動作します。各文字は6ビットを表すため、4つのグループはそれぞれ3バイト(それぞれ8ビット)にデコードされます。唯一の例外は、シンボルの数に依存する最後の4文字です=。 Base64 文字列は常に 4 に分割されます。

  • 0は3バイトにデコードされています
  • 1 = 2バイトでデコード
  • 2 == 1バイトでデコード

あなたの例ではHellと両方がoWor有効です。しかしld==それは真実ではない。理由を理解するには、次のルックアップテーブルを参照してください。 https://en.wikipedia.org/wiki/Base64

ld===最後に2バイトがあるので、1バイトだけでデコードする必要があります。ただし、ld次のようにデコードされます 100101 011101。 1バイトには8つの8ビットしかありません。したがって、文字列復号化を使用するとbase64 -dバイト100101 01にのみ変換され、終了は1101完全に無視されます。

で終わるすべてのBase 64文字列は、==最後の文字の最初の2文字のみを使用する必要があります。唯一の利用できる結末==Q== A== w== g==

答え2

はい、これはパディングとの相互作用です。

実際にエンコードされたデータをデコードして(ASCII文字列ではないので)バイナリに変換してみましょう。

$ base64 -d <<<'HelloWorld==' | xxd -b
00000000: 00011101 11101001 01100101 10100001 01101010 00101011  ..e.j+
00000006: 10010101                                               .

HelloWorld==Base64でエンコードされたデータ。フィリップ・クーリン最後の部分をデコードする複雑さを説明し、データをデコードするときにld==エンコードされたデータの1/3だけが実際に使用される程度まで説明します。以下では、データの記録時にソースをd表示します。Q

このバイナリを繰り返してみましょう。

00011101 11101001 01100101 10100001 01101010 00101011 10010101

6ビットグループ(Base64エンコーダが使用するもの):

000111 011110 100101 100101 101000 010110 101000 101011 100101 01

最後に、4つの0ビットを埋め、10の完全な6桁のコードを形成します。

000111 011110 100101 100101 101000 010110 101000 101011 100101 010000

これはデータの記録時に表示される内容010000です(参照:QBase64コードテーブル)。

答え3

パイプはきれいではありません。最初にエンコードしてからデコードする必要があります。

$ echo "Hello World!==" | base64 | base64 -id
Hello World!==

無効なBase64エンコーディング形式をデコードしています。

関連情報