若要手動將十六進位轉換為 Base64,請將每三個輸入位元組分組為 24 位元,再將這些位元切成四個 6 位元的區塊,然後在 RFC 4648 所定義的標準 Base64 字彙表中查找每個區塊的索引。當最後一組只包含一個或兩個位元組時,請在右側補上零填充位元以完成最後一個 6 位元區塊,然後附加一個或兩個 '=' 字元,使總字元數保持為 4 的倍數。反向路徑——從 Base64 回到十六進位——則是相反的過程:每四個 Base64 字元解碼為三個位元組,嚴格的驗證器還要求任何零填充位元確實為零,且 '=' 填充字元只能出現在句尾。這兩種編碼都是同一組位元組序列的無損表示,因此一趟乾淨的往返只能告訴你位元組是否完整存活;它無法說明資料是否經過加密、壓縮、簽章,或是否具有意義。本指南會帶你逐步走過手動計算的機制,並使用 RFC 4648 的標準測試向量,指出手動計算通常出錯的地方,以及在手動方式不再實用時,如何透過基於瀏覽器的工具執行相同的轉換。

為什麼十六進位和 Base64 看起來如此不同
十六進位(大多數程式設計師寫作「hex」的編碼方式)只是一種用每個位元組兩個數字來表示原始位元組的方法。每個數字帶有 4 位元的資訊,因此字串 66 實際上代表位元組 01100110,字串 666f 代表兩個位元組 01100110 01101111,依此類推。因此一個 16 位元組的雜湊值長度永遠是 32 個十六進位字元,除了十六進位數字對照表之外,你不需要任何特殊工具就能讀取或編輯它。
Base64 則是為不同的工作而設計的:將任意位元組塞進預期為文字的地方。它使用從 ASCII 範圍中取出的 64 字元字彙表,使輸出能夠在複製貼上、終端機、JSON 以及大多數舊式通訊協定中存活。因為 64 不是 2 的冪次,所以每個 Base64 字元帶有 6 位元而非 4 位元的資訊,標準作法是將原始位元組分組為三個一組(24 位元),再切割成四個輸出字元。這種額外的密度——比十六進位少了大約 33% 的額外負擔——就是為什麼 Base64 會出現在 MIME 電子郵件、JWT 權杖和資料 URL 中。
核心規則:3 個位元組變成 4 個 Base64 字元
整個手動轉換可歸結為一條規則:每三個輸入位元組正好產生四個 Base64 字元。標準字彙表(依據 RFC 4648)依序列出 26 個大寫字母、26 個小寫字母、數字 0 到 9,以及 '+' 和 '/'。索引 0 到 25 對應 A 到 Z,26 到 51 對應 a 到 z,52 到 61 對應 0 到 9,62 是 '+',63 是 '/'。
如果最後一組只包含一個或兩個位元組,編碼器會在位元流右側補零以填滿一個 6 位元區塊,然後附加 '=' 符號,使總長度保持為 4 的倍數。剩下一個位元組會產生兩個字元加上兩個 '=' 符號;剩下兩個位元組則產生三個字元加上一個 '=' 符號。尾端的零填充位元並非免費:嚴格的解碼器會拒絕任何將這些填充位元設為 1 的字串,因為那會產生同一組位元組的第二種、非標準的拼法。
RFC 4648 第 10 節的標準測試向量讓我們能輕鬆用手動方式驗證這個關係:
| ASCII 輸入 | 十六進位位元組 | Base64 輸出 | 解碼位元組數 |
|---|---|---|---|
| f | 66 | Zg== | 1 |
| fo | 666f | Zm8= | 2 |
| foo | 666f6f | Zm9v | 3 |
| foob | 666f6f62 | Zm9vYg== | 4 |
| fooba | 666f6f6261 | Zm9vYmE= | 5 |
| foobar | 666f6f626172 | Zm9vYmFy | 6 |
每一列都將左側的原始位元組打包成 6 位元區塊,並輸出由四個字元組成的 Base64 群組。空輸入(零個位元組)會變成空白的 Base64 字串。在你信任自己手動產生的結果之前,都應該與這些列中的某一列相符。
如何手動將十六進位轉換為 Base64
- 驗證十六進位字串。確認每個字元都是十六進位數字、總長度為偶數,並且沒有 0x 前綴、空白字元、底線或冒號。字串 66 6f 會被拒絕;字串 666f 則會被接受,並代表兩個位元組。
- 將每一對數字翻譯成一個位元組。串接位元:66 變成位元組 01100110,6f 變成 01101111,依此類推。請保持位元組的順序。
- 將位元組分組為三個一組的區塊。三個位元組產生 24 位元,正好是四個 6 位元的 Base64 區塊。如果尾部剩下一或兩個位元組,請先將它們擱置,留待填充步驟處理。
- 將每個 24 位元區塊分割成四個 6 位元區塊並翻譯。由左至右每次讀取 6 個位元,然後在標準字彙表中查找每個區塊:0 到 25 對應 A 到 Z,26 到 51 對應 a 到 z,52 到 61 對應 0 到 9,62 是 '+',63 是 '/'。
- 單一位元組的完整範例。取十六進位 66。該位元組為 01100110。在右側補零至 12 位元,得到 011001 100000。第一個區塊為二進位 011001,即十進位 25,也就是字母 'Z'。第二個區塊為二進位 100000,即十進位 32,也就是字母 'g'。至此輸出為「Zg」。
- 對最後一組套用填充。剩下一個位元組會產生兩個實際字元,因此附加兩個 '=' 符號以達到 4 的倍數:Zg==。剩下兩個位元組則產生三個實際字元加上一個 '=' 符號。剩下三個位元組則不需要任何 '='。
- 驗證零填充位元確實為零。如果你產生的是 ZgA= 而非 Zg==,那麼尾端的填充位元將不為零,嚴格的解碼器將會拒絕該拼法。乾淨的手動轉換永遠會產生 RFC 對照表中所列的標準形式。
手動轉換失效之處
手動轉換是學習編碼方式的實用練習,但它很少能擴展到實際工作。第一個陷阱是半位元組對齊。一個具有奇數位數的十六進位字串沒有定義明確的最後一個位元組,因此你所產生的任何結果都會悄悄偏移半個位元組,導致結果在下一輪往返中失敗。第二個陷阱是 base64url 變體,它將 '+' 和 '/' 替換為 '-' 和 '_',且通常完全捨棄 '=' 填充。許多命令列工具會以獨立的別名接受 base64url;如果你將這類字串貼到嚴格的標準 Base64 解碼器中,由於字彙表不符,它會立即失敗。
空白字元是第三個陷阱。RFC 4648 的標準 Base64 沒有內嵌換行,而 MIME 電子郵件和許多 CLI 編碼器則每 76 個字元插入一個換行符。嚴格的轉換器會拒絕經過換行處理的輸入,以避免猜測你想使用的變體,這在移除換行之前看起來像是無用的錯誤訊息。前導零是第四個陷阱。十六進位字串 0066 是兩個位元組(00000000 01100110),與 66(一個位元組)並不相同。略過前導零會悄悄縮短承載內容,並破壞雜湊值、簽章與精確的快取鍵。
最後,非標準的填充會讓兩個不同的 Base64 字串解碼為相同的位元組。字串 Zg== 與一個尾端填充位元被設為 1 的(錯誤)變體都代表相同的位元組,但只有標準形式能在與規格或已簽署權杖的往返比對中存活。手動計算正是那些錯誤會被引入且永遠不會被察覺的地方。
使用 Base64 轉十六進位轉換器執行轉換
當你需要的是答案而非教學時,Base64 轉十六進位轉換器會強制執行手動方法應遵循的相同規則:標準 RFC 4648 Base64 並必須有 '=' 填充、嚴格的每個位元組兩位數十六進位且不含 0x 前綴,以及位元組層級的驗證,能拒絕非標準的填充位元。轉換過程完全在瀏覽器本機執行,輸入資料從不離開你的電腦,且每次執行的輸入上限為 500,000 個解碼位元組。轉換採用數值型位元組陣列而非瀏覽器的文字強制轉型,格式錯誤的輸入會產生明確的錯誤且不會產生部分結果,而複製動作只會複製轉換後的值。
若要使用它將十六進位轉換為 Base64:
- 選擇「hex to Base64」方向,並確認你的輸入是標準 RFC 4648 Base64 或每個位元組兩位數的十六進位,而非 base64url 或經過換行的 MIME 變體。
- 貼上不含空白、0x 前綴、底線或分隔符的十六進位字串。如果十六進位內容以前導零位元組開頭,請保留它們:0066 是兩個位元組,而非一個。
- 執行轉換,檢查回報的位元組長度是否符合預期,確認前導零在結果中顯示為 00,然後複製精確的 Base64 輸出。
對於偏重程式碼的讀者而言,相同的轉換可以使用 binascii.hexlify 和 base64.b64encode 等程式庫呼叫來實作;該路徑的完整演練收錄於在 Python 中將十六進位轉換為 Base64 而不破壞位元組。瀏覽器工具在臨時檢查時速度更快,並消除了手動計算可能出錯的所有環節。
想深入了解,請參閱將檔案轉換為 Base64 以用於 Postman 請求。