Base100 編碼會把每一個 UTF-8 位元組,對映到一個表情符號範圍內的 code point,從 U+1F3F7(位元組 0)到 U+1F4F6(位元組 255),使用的公式是 code point = U+1F3F7 + 位元組值。無論是命令列指令碼,還是以瀏覽器為基礎的編碼器,內部都採用同一套「位元組加偏移量」的公式,但這兩種使用方式,在設定、驗證,以及如何處理符號串流邊緣情況上,卻有很大的差異。命令列工具在終端機中執行,透過同一套對映把位元組傳遞過去,再透過 stdout 或檔案重新導向把結果回傳。線上編碼器則把完全相同的公式包在一個瀏覽器表單裡:你貼上文字,頁面在記憶體中把位元組對映成 code point,你再把結果以符號串流的形式複製出來,過程中不會有任何內容被上傳。要選擇哪一種,通常取決於這項任務是自動化的(寫成指令碼、批次處理、內嵌在建置流程中),還是互動式的(一次性的轉換、解碼別人傳來的串流、快速檢查一段看起來怪怪的貼上內容)。

Base100 對映實際上是如何運作的
Base100 是 Adam Niederer 最初在 base100 GitHub 專案中發布的位元組轉 code point 對映方式。這套編碼會先把輸入字串轉換成 UTF-8,接著把每一個落在 0–255 範圍內的位元組 b,輸出成單一一個 Unicode code point U+1F3F7 + b。輸出字母表恰好有 256 個 code point,在輔助多語言平面中連續排列,從 U+1F3F7 一路到 U+1F4F6。這套對映是一對一的,所以同一個 code point 永遠代表同一個位元組,而解碼就只是先做減法、再重建 UTF-8。
實際範例:以位元組值 65、也就是 ASCII 字母 A 為例。0x1F3F7 換算成十進位是 127,991,而 127,991 + 65 = 128,056,也就是 U+1F438。所以輸入中一個 ASCII「A」,會在輸出中恰好產生一個 U+1F438 符號。位元組 255 會產生 U+1F4F6(127,991 + 255 = 128,246,換算成十六進位就是 0x1F4F6),而位元組 0 則會產生 U+1F3F7 本身。位元組之間不會插入任何填充、分隔符、檢查碼、長度標記,或語意轉換──輸出長度永遠恰好等於輸入內容的 UTF-8 位元組數。
正是這種位元組層級的框架方式,讓命令列與線上工具之間的選擇,比乍看之下更值得玩味。兩種模式都必須先把輸入轉換成 UTF-8,逐一走過每個位元組,再套用偏移量。差異來自於各自如何接收輸入、如何呈現錯誤,以及在這套對映邊緣情況下會發生什麼──包括一個常見的陷阱:使用者輸入的一個字元,可能會展開成好幾個 UTF-8 位元組,因此也會變成好幾個 Base100 符號。
命令列 vs 線上:並排比較
| 面向 | 命令列版 Base100 | 線上版 Base100 編碼器 |
|---|---|---|
| 設定 | 安裝一套 CLI 實作(原始的 Rust 執行檔,或用 Python、Go 或其他語言移植的版本) | 開啟頁面即可;不需要安裝 |
| 網路 | 只有一次性安裝時需要 | 只有載入頁面時需要;之後的轉換都在本機端執行 |
| 輸入管道 | stdin 管線、檔案重新導向,或參數 | 貼進文字區塊 |
| 輸出管道 | stdout 串流,可重新導向到檔案 | 顯示在頁面上的符號串流,可複製到剪貼簿 |
| UTF-8 邊界處理 | 由執行環境與作業系統的語系設定處理 | 依照 WHATWG 編碼標準由瀏覽器處理 |
| 嚴格解碼行為 | 視實作而定 | 拒絕空格、換行、變體選擇符,以及超出範圍的 code point;把無效的 UTF-8 回報為錯誤 |
| 可寫成指令碼 | 可以──適合放進管線、迴圈與建置步驟 | 不能直接做到;需要在頁面外圍搭配自動化工具 |
| 輸入內容隱私性 | 預設在本機端處理 | 轉換在瀏覽器中執行時,預設在本機端處理 |
| 不小心貼上超大內容 | 由 shell 或檔案系統截斷,而不是由工具本身截斷 | 上限為 500,000 位元組或符號,以保護分頁 |
這兩欄共用同一套數學核心。差異在於使用體驗:CLI 很適合融入管線或 CI 步驟中,而瀏覽器工具則很適合處理一次性任務,也就是輸入內容已經在你的剪貼簿裡、或是別人以訊息形式傳給你的情況。
從命令列執行 Base100
原始實作是 Adam Niederer 用 Rust 寫成的專案;另外還有好幾個用 Python、Go 與其他語言移植、實作同一套「位元組加偏移量」公式的版本。無論你選用哪一種執行環境,工作流程都是相同的:
- 安裝或建置一套 Base100 CLI。如果是原始的 Rust 原始碼,用 cargo 建置;如果是 Python 移植版,用 pip 安裝;如果是 Go 移植版,用 go install 安裝。選擇與你其餘工具鏈相符的那一個。
- 把輸入內容準備成 UTF-8 格式。把訊息存成檔案,或從另一個指令用管線傳進來。請確認終端機的語系設定會產生 UTF-8,因為在錯誤的編碼下展開的非 ASCII 文字,會編碼出錯誤的位元組,還原後會變成亂碼。
- 呼叫編碼器,把 UTF-8 輸入透過 stdin 或以檔案參數傳入。這個工具會逐一走過每個位元組,對每一個都套用 U+1F3F7 + b,並把產生的 code point 以單一、不中斷的符號串流寫到 stdout。
- 擷取輸出結果。如果需要分享,就把 stdout 重新導向到檔案,或直接從終端機複製這串符號。複製時不要加入空格、換行,或變體選擇符──嚴格解碼器會拒絕它們。
- 要解碼的話,反過來操作:把 Base100 串流用管線傳給解碼器,或以參數傳入。嚴格解碼器會把每一個 code point 都減去 U+1F3F7,檢查結果是否落在 0–255 範圍內,再把這些位元組重新解讀為 UTF-8。
- 做個健全性檢查,確認來回轉換正確。對同一段 UTF-8 文字先編碼、再解碼,應該要得到原本的字元。任何不一致,都代表某個符號在傳輸過程中被遺漏、被加入了變體選擇符,或被替換掉了。
CLI 在 shell 管線中運作得很好,因為 Base100 沒有任何需要剝除的封裝負擔:沒有填充、沒有標頭、沒有檢查碼、沒有長度標記。但缺點也正是同一個原因:沒有內建的機制可以檢查複製貼上後的串流是否完整無損,所以單一一個字元被替換掉,就會在解碼後的文字中造成一個位元組的變化,而且不會有任何警告。
在瀏覽器中編碼或解碼 Base100
同一套公式的瀏覽器版本,位於 Base100 Encoder / Decoder 頁面,步驟與 CLI 流程大致對應,只是把 stdout 管線換成了一個文字區塊:
- 如果要編碼,選擇 Text to Base100;如果要解碼,選擇 Base100 to text。
- 把你的 UTF-8 文字(用於編碼)或 Base100 符號串流(用於解碼)貼進輸入區域。空白輸入會被拒絕,而不是悄悄產出空白的輸出結果。
- 執行轉換。編碼器會把每個 UTF-8 位元組對映到 U+1F3F7–U+1F4F6 之間的一個 code point;解碼器則會減去這個偏移量,並驗證結果是否為有效的 UTF-8。
- 從結果區域複製輸出內容。複製時不要加入空格、換行、標點符號,或變體選擇符──嚴格解碼器在回頭解碼時會拒絕它們。
- 如果解碼失敗並顯示錯誤,代表這些位元組不是有效的 UTF-8 序列,或是輸入內容中含有超出 Base100 範圍的 code point。頁面會回報這個失敗,而不是悄悄替換成替代字元、假裝結果是精確的。
因為轉換是在瀏覽器中於本機端執行,輸入內容永遠不會被上傳到伺服器。這個頁面對任一方向都強制設有 500,000 位元組或 500,000 符號的上限,避免失控的貼上內容凍結分頁,而在這個上限之內的輸出,永遠不會被悄悄截斷。
為什麼符號數量與字元數量對不上
比較命令列與線上工具的行為時,最常見的意外之處就是輸出長度。一段 10 個字元的 ASCII 訊息,永遠會產生 10 個 Base100 符號,因為每個 ASCII 字元恰好是一個 UTF-8 位元組。而一段包含帶重音字母、中日韓表意文字,或表情符號的 10 個字元字串,通常會產生超過 10 個符號,因為這些字元會被編碼成多個 UTF-8 位元組,而 Base100 對映的是位元組,不是字元。因此,符號數量計算的是已編碼的位元組數,而不是使用者感知到的字元、字素叢集、單字,或輸入內容的 JavaScript 字串長度。如果 CLI 與線上工具在同樣的輸入上,長度出現不一致,原因幾乎總是語系設定不一致(CLI 編碼出的位元組序列,與瀏覽器編碼出的不同),而不是公式本身有差異。
當一段串流解碼失敗時
嚴格解碼會拒絕任何不屬於那 256 個 code point 字母表的內容。空格、換行、標點符號、變體選擇符,以及 U+1F3F7–U+1F4F6 範圍以外的表情符號,在原始格式中都不是封裝語法;它們是聊天應用程式、編輯器、鍵盤,或正規化處理管線意外加入的裝飾。一段在螢幕上看起來很相似的串流,實際上可能在位元組層級不同,因而無法通過嚴格檢查。發生這種情況時,請從不會轉換 Unicode 的來源──純文字編輯器、十六進位傾印,或程式化匯出──重新複製原始串流,再試一次。這個頁面會把無效的 UTF-8 回報為明確的錯誤,而不是悄悄插入 U+FFFD 替代字元,所以解碼失敗代表這些位元組真的有問題,而不是這個工具在過度謹慎。
為這項工作選擇正確的做法
當任務是可重複執行的──像是建置步驟、處理一整個資料夾檔案的指令碼,或任何必須無人值守執行的工作──就選用命令列。當任務是一次性的──像是一段可疑的貼上內容、別人轉傳給你的串流、你想為聊天訊息編碼的一小段內容,或編輯檔案後想快速做的來回檢查──就選用線上工具。因為公式共通,只要兩端在邊界上都採用 UTF-8,且串流中沒有任何字元在傳輸過程中被轉換過,你就可以在兩者之間切換而不會有意外狀況。若想了解完整的本機端執行觀點,把 Base100 對映當成 API 替代方案、在本機端執行這篇指南,說明了如何以可寫成指令碼的形式,運用同一套「位元組加偏移量」的公式。
若想進一步了解,請參閱Base64 Decode 命令列 vs 線上:實用指南。