Base64

為什麼從 base64 轉換並返回此字元串的末尾會出現亂碼?

  • August 28, 2019

命令:

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

輸出:

HelloWorlQ==

為什麼我的d現在是一個Q

編輯:

我不想從任意數據開始並對其進行 base64 編碼。我的意圖是從 Base64 開始並以 Base64 結束,在此期間只產生了一個二進制值。

編輯 2

我注意到如果輸入字元串是四個字元的倍數,則不會發生這種情況,所以我認為這是與填充的互動:

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

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

編輯 3

刪除了對標誌的混淆提及-i,結果證明這與我的問題無關。

是的,這是與填充的互動。

讓我們通過解碼來查看您的實際編碼數據,並且(因為它不是 ASCII 字元串)將其轉換為二進制:

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

這是HelloWorld==base64編碼的數據。Philip Couling解釋了最後ld==一部分解碼的複雜性,並且在某種程度上,d在解碼數據時實際使用了由 1/3 編碼的數據。下面我將展示Q重新編碼數據時的來源。

讓我們重複那個二進製文件:

00011101 11101001 01100101 10100001 01101010 00101011 10010101

以六位為一組(這是 base64 編碼器將使用的):

000111 011110 100101 100101 101000 010110 101000 101011 100101 01

這在末尾填充了四個零位,以形成 10 個完整的 6 位程式碼:

000111 011110 100101 100101 101000 010110 101000 101011 100101 010000

010000Q您在重新編碼數據時看到的(參見 base64 程式碼表)。

HelloWorld==包含無法解碼的資訊,並且在技術上不是有效的 Base64,因為它們通常應該被0填充。當1echo "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==應該只解碼為一個字節,因為它最後有兩個=。但ld解碼為: 100101 011101. 一個字節只有八個 8 位。因此,當您使用 解碼字元串時base64 -d,only100101 01將被轉換為字節,並且結尾1101將被完全忽略。

任何以 64 為結尾的字元串==只能使用最後一個字元的前兩位。那是唯一有效的結尾==Q== A== w== g==

引用自:https://unix.stackexchange.com/questions/537376