Base64 是一種二進位制轉文字的編碼方法,用於以 ASCII 字串格式表示二進位制資料。它常用於對以文字為主的介質(例如電子郵件、基於 JSON 的 API 等)進行資料編碼,以確保影像和檔案等二進位制資料不會損壞。Base64 一詞源於它使用 64 個字元(A-Z、a-z、0-9、+ 和 /)來表示資料。近年來,Base64 已廣泛應用於多模態 AI 應用、嵌入式系統、雲服務和 Web 開發。在本文中,我們將深入瞭解 Base64 及其使用方法。
為什麼選擇Base64?
Base64 主要用於需要將二進位制資料(例如影像、影片、模型權重等)在基於文字的基礎架構中傳輸且不被篡改或損壞的情況。但為什麼它在眾多其他型別的編碼中如此受歡迎呢?讓我們來一探究竟。
Base64 具有以下特點:
- 文字安全:可以將二進位制資料嵌入 HTML、XML、JSON 等文字格式。
- 易於傳輸:不存在字元編碼或資料損壞問題。
- 常用於影像:在 Web 開發中,常用於將影像直接嵌入 HTML/CSS 或 JSON 負載中。
以下是其他著名編碼與 Base64 的比較。
編碼 | 目的 | 使用案例 | 大小影響 |
---|---|---|---|
Base64 | 二進位制轉文字 | 在 HTML、JSON 等中嵌入影像/檔案 | 大約增加 33% |
Hex | 二進位制轉十六進位制 | 除錯、網路追蹤 | 大約增加 100% |
Gzip | 壓縮 | 文字/二進位制的實際大小減少 | 視壓縮比而定 |
Base64是如何工作的?
現在讓我們嘗試理解 Base64 的工作原理。以下是將字串“Hello”轉換為 Base64 格式的分步演示。
步驟 1:將文字轉換為 ASCII 位元組
字元 | ASCII 十進位制值 | 二進位制值(8 位) |
H | 72 | 01001000 |
e | 101 | 01100101 |
l | 108 | 01101100 |
l | 108 | 01101100 |
o | 111 | 01101111 |
所以現在,我們的字串“Hello”看起來應該是 01001000 01100101 01101100 01101100 01101111。
也就是 5 個字元 × 8 位 = 40 位。
步驟 2:將二進位制數拆分成6位組
Base64 以 6 位為單位進行操作,因此我們將這 40 位資料分組為 6 位資料塊,而之前是 8 位資料塊:
01001000 01100101 01101100 01101100 01101111
當這些 8 位資料塊被拆分成 6 位資料塊時,結果如下:
010010 000110 010101 101100 011011 000110 1111
由於 40 不能被 6 整除,因此我們需要在末尾填充一些 0。現在我們有 6 個完整的 6 位資料塊和 1 個剩餘的 4 位資料塊。我們在最後一個塊中填充 2 個零位,使其成為一個完整的 6 位資料塊:
010010 000110 010101 101100 011011 000110 111100
步驟 3:將6位組轉換為十進位制
我們知道 2^6 等於 64。因此,我們的範圍在 0 到 63 之間。
6位二進位制 | 十進位制 |
010010 | 18 |
000110 | 6 |
010101 | 21 |
101100 | 44 |
011011 | 27 |
000110 | 6 |
111100 | 60 |
步驟 4:對映到Base64字元
按照標準 Base64 字元表,我們將十進位制值對映到相應的字元。
Source – Link
十進位制 | Base64 字元 |
18 | S |
6 | G |
21 | V |
44 | s |
27 | b |
6 | G |
60 | 8 |
我們得到的字串“Hello”的 Base64 編碼結果為“SGVsbG8”。
步驟 5:新增填充
由於原始字串有 5 個位元組(不是 3 的倍數),Base64 需要使用“=”進行填充,使輸出長度成為 4 個字元的倍數。
5 個位元組 = 40 位 -> 6 個完整的 Base64 字元 + 2 個字元(來自填充位)-> 總共 8 個字元
最終的 Base64 編碼字串:“Hello” -> SGVsbG8=
Base64的Python實現
現在您已經瞭解了 Base64 的工作原理,接下來我將向您展示如何在 Python 中實現它。我們將首先嚐試對一些文字進行編碼和解碼,然後對影像進行同樣的操作。
文字編碼和解碼
讓我們使用 Base64 對這段簡單的文字進行編碼,然後將編碼後的字串解碼回其原始形式。
import base64 # Text encoding message = "Hello World" encoded = base64.b64encode(message.encode()) print("Encoded:", encoded) # Decoding it back decoded = base64.b64decode(encoded).decode() print("Decoded:", decoded)
輸出:
影像編碼和解碼
在視覺相關的應用中,尤其是在使用視覺語言模型 (VLM) 時,影像通常在以下情況下使用 Base64 編碼:
- 透過 JSON 負載與 API 之間傳輸影像;
- 嵌入影像以訓練和提供多模態模型;
- 使用 CLIP、BLIP、LLaVA 或其他視覺語言轉換器,將影像作為序列化的 Base64 字串進行處理。
以下是一段簡單的 Python 影像編碼和解碼程式碼。
from PIL import Image import base64 import io # Load and encode image img = Image.open("example.jpeg") buffered = io.BytesIO() img.save(buffered, format="JPEG") img_bytes = buffered.getvalue() img_base64 = base64.b64encode(img_bytes).decode('utf-8') print("Base64 String:", img_base64[:100], "...") # Truncated
輸出
我們還可以使用以下程式碼將 base64 編碼的資料解碼回影像。
from PIL import Image import base64 import io from IPython.display import display, Image as IPythonImage # Assume `img_base64` is the base64 string img_data = base64.b64decode(img_base64) img = Image.open(io.BytesIO(img_data)) display(IPythonImage(data=img_data))
輸出
要了解有關 Base64 的更多資訊並查詢更多編碼器和解碼器,您可以參考此網站。
使用Base64時需要注意的事項
儘管 Base64 在跨領域的各種用例中都非常有用,但在使用它時仍需注意以下幾點。
- 大小開銷(約 33%):每 3 個位元組的二進位制資料,需要輸出 4 個位元組的文字。對於大批次資料(例如,數千個高解析度幀),這會快速消耗網路和儲存頻寬。請考慮在 Base64 之前壓縮影像 (JPEG/PNG),並儘可能使用流式傳輸。
- 記憶體和 CPU 負載:一次性轉換和緩衝整張圖片會導致編碼期間記憶體使用量激增。同樣,解碼為原始位元組,然後透過圖片庫進行解析也會增加 CPU 開銷。
- Base64 並非壓縮演算法:Base64 不會減小資料大小,而是會使資料膨脹。在編碼為 Base64 之前,請務必對二進位制資料進行真正的壓縮(例如,JPEG、WebP)。
- 安全注意事項:如果我們盲目地將 Base64 字串連線到 HTML 或 JSON 中而不進行清理,則可能會開啟 XSS 或 JSON 注入向量。此外,極大的 Base64 資料可能會耗盡解析器,並在閘道器處強制執行最大有效載荷大小。
小結
在這個模型既能“看”又能“讀”的時代,Base64 已悄然成為多模態系統的基石。它在資料編碼中扮演著至關重要的角色,彌合了二進位制資料和純文字系統之間的鴻溝。在視覺語言工作流程中,Base64 標準化了影像從移動客戶端到雲端 GPU 的傳輸方式,同時保持了可重複性並簡化了整合。
使影像與基於文字的基礎設施相容一直是一個複雜的難題。Base64 編碼為此提供了一個實用的解決方案,它支援透過 API 傳輸影像,並打包資料集用於訓練。
評論留言