Base100 編碼會將每個 UTF-8 位元組對應到 U+1F3F7 到 U+1F4F6(含)這個範圍內的一個 Unicode 碼位,使用的公式只有 碼位 = U+1F3F7 + 位元組值,因此位元組 0 變成 U+1F3F7,位元組 1 變成 U+1F3F8,位元組 255 變成 U+1F4F6。編碼字串時,實作會先將其轉為 UTF-8,再把產生的每個位元組轉成 256 個保留的表情符號範圍碼位之一;解碼時則逐個讀取輸入的碼位,減去 U+1F3F7 還原每個位元組,然後將該位元組序列送進嚴格的 UTF-8 驗證器。輸出是一串可見的表情符號狀符號,每個輸入位元組對應一個符號,沒有填補符、分隔符、長度標記或校驗和。由於對應關係純粹是算術,而且任何知道偏移量的人都可以完整還原,Base100 被視為位元組編碼而非安全性工具。該合約的每個部分都由 Base100 編碼 / 解碼器 在本地端實作,所有編碼和解碼都在瀏覽器中進行,不會上傳輸入內容。

base100 encode explained
Base100 編碼解析:位元組到表情符號的公式

位元組到碼位的公式如何運作

Adam Niederer 的 Base100 專案 所提出的對應關係就是完整規格:取一個位元組,加上 U+1F3F7,就得到符號。以下三個具體的位元組值在公式的兩端和中間作為定位點:

  • 位元組 0 → U+1F3F7
  • 位元組 1 → U+1F3F8
  • 位元組 255 → U+1F4F6

以可列印的 ASCII 字元(例如字母「A」)為例,其輸入位元組為 65。代入 碼位 = U+1F3F7 + 65 得到 0x1F3F7 + 0x41 = 0x1F438,這就是「A」對應的 Base100 渲染符號。由於每個位元組只對應到一個符號,Base100 串流的符號數等於來源文字的 UTF-8 位元組數,絕不是使用者感知的字元數。沒有分塊、沒有壓縮,也沒有語義轉譯——表情符號的名稱、意義和視覺分類都不帶任何資訊,這些只是使用多數字型會以表情符號字形呈現的碼位範圍所造成的副作用。

獨立的 Go 實作 Dongle Base100 文件記錄了相同的位元組公式,任何符合規範的解碼器只需要偏移量 U+1F3F7 就能還原位元組。WHATWG 編碼標準 定義了 JavaScript 字串與位元組界面上使用的 UTF-8 行為,這正是嚴格解碼器能夠拒絕格式錯誤的 UTF-8,而非靜默地將其替換為 U+FFFD 替換字元的原因。

為何 Base100 一定要先經過 UTF-8

Base100 操作的對象不是 JavaScript 字元、字素叢集或單詞,而是位元組。JavaScript 字串是 UTF-16 碼位的序列,位於基本多文種平面外的字元會使用代理對,因此把「字元」視為基本單位會遺失資訊。為了避免這個問題,編碼器一律先把輸入字串轉成 UTF-8,產生一個位元組序列,其中每個字元恰好使用 UTF-8 標準所要求的位元組數。一般的 ASCII 文字會為每個字元產生一個 Base100 符號,因為每個 ASCII 字元都是單一位元組的 UTF-8。非 ASCII 文字通常會膨脹:帶變音符號的拉丁字母變成兩個位元組,CJK 字元變成三個位元組,而大多數表情符號等輔助平面字元則變成四個位元組。因此,一個使用者感知的單一字元可能產生兩個、三個或四個 Base100 符號。

這種膨脹正是為何 Base100 輸出串流以位元組而非字元來衡量,也正是為何短短一段使用者字串可能產生明顯較長的符號串流。例如,單一字元字串「é」是一個 UTF-16 碼位,卻是兩個 UTF-8 位元組(0xC3 0xA9),因此其 Base100 輸出包含兩個符號而非一個。貼上 CJK 文字、表情符號或帶變音符號字母的使用者,應該預期符號數大約會依輸入的 UTF-8 大小成比例增加,而不應該試圖從輸出的「字元」數去估算原始長度。

如何使用 Base100 編碼 / 解碼器

Base100 編碼 / 解碼器在同一頁面提供兩種操作,兩者都在瀏覽器本地端執行。以下步驟涵蓋兩個方向。

  1. 開啟 Base100 編碼 / 解碼器頁面。
  2. 選擇 文字轉 Base100 進行編碼,或選擇 Base100 轉文字 進行解碼。
  3. 編碼時:在輸入欄框中輸入或貼上 UTF-8 文字。工具會先將字串轉成 UTF-8,再把每個位元組對應到 U+1F3F7 到 U+1F4F6 範圍內的一個碼位。
  4. 執行轉換。輸出會以一串連續的表情符號範圍符號呈現,不會加入額外的空格、換行或變化選擇器。
  5. 請完全按照產生的結果複製輸出。不要在符號之間插入空白、標點或表情符號裝飾——這些字元在原始格式中並非外框語法。
  6. 解碼時:切換到 Base100 轉文字,並將未經修改的符號串流貼到輸入欄框。
  7. 執行解碼器。每個符號都必須落在 U+1F3F7 到 U+1F4F6 之內;空格、換行、變化選擇器以及範圍外的表情符號都會被拒絕。
  8. 若位元組構成有效的 UTF-8,便會顯示原始文字。若不構成有效 UTF-8,工具會回報錯誤,而非假裝結果是精確的。

頁面在任一方向上限制為 500,000 位元組或符號,以免意外貼上大量內容導致瀏覽器卡住。空輸入會被拒絕,輸出絕不會被靜默截斷,解碼則採用嚴格的 UTF-8 驗證。如果你偏好逐步演練的範例而非即時工具,可以參考 Base100 編碼逐步演練

解碼器會拒絕哪些內容,以及原因

嚴格的 Base100 解碼刻意毫不寬容。解碼器依 Unicode 碼位而非 UTF-16 碼位讀取輸入,這代表它以原始格式的方式來計算符號。每個符號都必須落在 U+1F3F7 到 U+1F4F6(含)的範圍內,任何落在該範圍外的字元——包括空格、換行、標點、變化選擇器,以及恰好差一個碼位的表情符號——都會導致解碼失敗。接著透過減去 U+1F3F7 還原位元組值,產生的位元組序列會送進嚴格的 UTF-8 解碼器。若位元組不構成有效的 UTF-8 序列,工具會回報錯誤,而不會靜默插入替換字元,將有損的結果呈現為精確的內容。

這種嚴格性在實務上很重要,因為聊天應用程式、編輯器、鍵盤與正規化管線經常會插入不可見字元。因此,看起來在螢幕上一模一樣的串流,實際上位元組層級可能不同,並在嚴格解碼時失敗。常見的元凶包括變化選擇器 U+FE0F(有些平台會附加在形似表情符號的字元後),以及會分解或重新組合碼位的正規化形式。在需要互通性時請保留精確的碼位;若貼上後突然無法解碼,應將不可見的裝飾視為最可能的原因。獨立的測試資料會鎖定下限與上限碼位,以及代表性的位元組偏移,確保對應關係每次的行為都一致。

Base100 與其他位元組編碼的比較

Base100 是多種可還原位元組編碼中的其中一種選項,正確的選擇取決於目的地所預期的內容。下表針對通常會影響決策的幾項標準,比較 Base100、Base64、Base32 與十六進位。

編碼方式 輸出字元集 每個位元組的符號數 ASCII 安全傳輸 典型用途
Base100 U+1F3F7 到 U+1F4F6(表情符號範圍) 每個符號 1 位元組 否(每個符號為多位元組 UTF-8) 視覺化、有趣、位元組精確的串流
Base64 A–Z、a–z、0–9、+、/、= 每個位元組約 1.33 個符號 電子郵件、JSON、資料 URI、權杖
Base32 (RFC 4648) A–Z、2–7、= 每個位元組約 1.6 個符號 不區分大小寫、由人工輸入的代碼
十六進位 0–9、a–f(或 A–F) 每個位元組 2 個符號 除錯傾印、校驗和、位元組層級檢查

若目的地要求僅限 ASCII 的傳輸,Base64、Base32 或十六進位通常相容性較高;Base100 的表情符號範圍輸出使用多位元組 UTF-8 序列,可能會被中間系統替換或加上裝飾。若目標是視覺上獨特、位元組逐一精確還原的串流,且目的地會保留表情符號碼位,那麼 Base100 是合適的選擇。

你應該了解的安全性與限制

Base100 是一種編碼,而非加密、雜湊、簽章、驗證、壓縮或隱寫術,它不提供機密性或完整性保證。任何知道偏移量 U+1F3F7 的人都可以還原輸入的每個位元組;語法上有效但遭到竄改的符號只會恰好改變一個位元組,卻沒有任何內建校驗和能標示出差異。請將 Base100 視同明文:適合用於在會保留表情符號範圍的系統中傳遞位元組,卻不適合用於保護密碼、個人資料、私鑰、權杖或機密訊息。若需要機密性與竄改偵測,請使用經過審查的加密與經認證的格式。

表情符號的渲染會因為作業系統、字型、瀏覽器和訊息平台而異,因此同一個碼位可能呈現為彩色圖像、單色字形、豆腐方塊或出乎意料的象形圖。渲染絕不會改變符合規範的字串內部的數學對應關係,但若經過會替換、去除或裝飾字元的系統複製,可能會改變底層的碼位,導致嚴格解碼失敗。解碼器刻意拒絕這些轉換,而不會去猜測。若需要更廣泛的邊界情況與復原技巧清單,Base100 速查表 將常見的失敗模式集中整理在同一處。