深入解析Base64編碼原理與應用指南

深入解析Base64編碼原理與應用指南

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 字元表,我們將十進位制值對映到相應的字元。

標準 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 對這段簡單的文字進行編碼,然後將編碼後的字串解碼回其原始形式。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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)
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)
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 影像編碼和解碼程式碼。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
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
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 編碼的資料解碼回影像。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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))
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))
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))

輸出

機器人basic64

要了解有關 Base64 的更多資訊並查詢更多編碼器和解碼器,您可以參考此網站

使用Base64時需要注意的事項

儘管 Base64 在跨領域的各種用例中都非常有用,但在使用它時仍需注意以下幾點。

  1. 大小開銷(約 33%):每 3 個位元組的二進位制資料,需要輸出 4 個位元組的文字。對於大批次資料(例如,數千個高解析度幀),這會快速消耗網路和儲存頻寬。請考慮在 Base64 之前壓縮影像 (JPEG/PNG),並儘可能使用流式傳輸。
  2. 記憶體和 CPU 負載:一次性轉換和緩衝整張圖片會導致編碼期間記憶體使用量激增。同樣,解碼為原始位元組,然後透過圖片庫進行解析也會增加 CPU 開銷。
  3. Base64 並非壓縮演算法:Base64 不會減小資料大小,而是會使資料膨脹。在編碼為 Base64 之前,請務必對二進位制資料進行真正的壓縮(例如,JPEG、WebP)。
  4. 安全注意事項:如果我們盲目地將 Base64 字串連線到 HTML 或 JSON 中而不進行清理,則可能會開啟 XSS 或 JSON 注入向量。此外,極大的 Base64 資料可能會耗盡解析器,並在閘道器處強制執行最大有效載荷大小。

小結

在這個模型既能“看”又能“讀”的時代,Base64 已悄然成為多模態系統的基石。它在資料編碼中扮演著至關重要的角色,彌合了二進位制資料和純文字系統之間的鴻溝。在視覺語言工作流程中,Base64 標準化了影像從移動客戶端到雲端 GPU 的傳輸方式,同時保持了可重複性並簡化了整合。

使影像與基於文字的基礎設施相容一直是一個複雜的難題。Base64 編碼為此提供了一個實用的解決方案,它支援透過 API 傳輸影像,並打包資料集用於訓練。

評論留言