Base100 透過將每個位元組轉成 U+1F3F7 到 U+1F4F6 之間的單一 Unicode 碼位來編碼 UTF-8 字串,使用公式 code_point = U+1F3F7 + byte_value,其中 byte_value 從 0 跑到 255。位元組 0 對應到 U+1F3F7,位元組 1 對應到 U+1F3F8,位元組 255 對應到 U+1F4F6。轉換程序在 Base100 編碼器 / 解碼器中執行,它會先把輸入文字轉成其 UTF-8 位元組序列,再為每個位元組產生剛好一個符號。一個簡單的 ASCII 範例可以把規則說明得很具體:字母 "A" 是位元組 65,所以 65 加上 U+1F3F7(十進位 127991)得到 U+1F438 — 一個代表原始輸入中一個位元組的單一符號。因為這個對應在包含 256 個碼位的範圍內嚴格維持 1 位元組對 1 碼位,所以每個 Base100 編碼範例都有相同的結構:一個加在固定起始碼位上的數字偏移,獨立套用到位元組。最終結果就是一串沒有分隔符號、填補、長度標記或校驗和的表情符號範圍符號。

base100 encode example
base100 encode example

位元組到符號的對應是如何定義的

Base100 是由 Adam Niederer 提出,作為教學範例展示單一位元組如何藏在輔助多語言平面內。原始的 Rust 實作就附帶了這個精確的位元組到碼位公式,一個獨立的 Go 函式庫也記錄了相同的位元組算術,這正是讓這個格式在不同工具之間保持穩定的原因。對應本身是固定且公開的,這也是這個編碼可以還原的原因:任何拿到表格的人都能還原原始位元組。三個官方界線構成了這個格式的錨點:

位元組值碼位角色
0U+1F3F7範圍內的第一個符號
1U+1F3F8範圍內的第二個符號
128U+1F477範圍的中點
255U+1F4F6範圍內的最後一個符號

因為位元組值是直接加到 U+1F3F7 上,產生的碼位會在輔助多語言平面內形成一個連續的 256 個值的區塊。編碼器為每個位元組產生一個符號,不會填補、沒有分隔符、沒有校驗和、不壓縮、沒有長度標記、符號之間也沒有意義上的轉換。在 U+1F3F7..U+1F4F6 以外的任何碼位都不是有效的 Base100 符號,編碼器也不會自行產生任何。一旦知道輸入的 UTF-8 位元組,用同一張表格就能夠用手算出任何 Base100 編碼範例。

一個逐步演練的範例:逐位元組編碼 "Hi!"

一個小而完全可追蹤的範例,可以展示公式的每一步,而不需要借助外部工具。讓我們用輸入字串 "Hi!" 並逐步走過一次。

公式: code point = U+1F3F7 + byte 數字錨點: U+1F3F7 = 十進位 127991

步驟 1 — 把輸入轉成 UTF-8 位元組。 ASCII 字元每個佔一個位元組,所以三個字元產生三個位元組:

  • "H" → byte 72 (0x48)
  • "i" → byte 105 (0x69)
  • "!" → byte 33 (0x21)

步驟 2 — 把偏移套用到每個位元組。 為每個十進位的位元組加上 127991,再換算回十六進位,就得到 Base100 碼位:

  • 127991 + 72 = 128063 → U+1F43F
  • 127991 + 105 = 128096 → U+1F460
  • 127991 + 33 = 128024 → U+1F418

步驟 3 — 依序串接符號。 輸出串流依序是 U+1F43F,然後 U+1F460,再來是 U+1F418,符號之間沒有任何分隔。輸入產生三個位元組,編碼器就回傳三個符號。這個 1:1 的關係就是每個 Base100 編碼範例對於純 ASCII 文字所呈現的相同形態,因為原始的 ASCII 編碼本身就已經是一個字元一個位元組。

逐步編碼 Base100 範例

驗證上述逐步範例最快速的方式,是透過瀏覽器工具重現一次。同一個畫面也能反向執行編碼以進行解碼。

  1. 打開 Base100 編碼器 / 解碼器,選擇「Text to Base100」模式。
  2. 輸入或貼上你想編碼的 UTF-8 文字,例如簡短訊息、程式碼片段,或是逐步範例中的 "Hi!" 字串。
  3. 執行編碼器,讓 UTF-8 表示法中的每個位元組對應到 U+1F3F7 到 U+1F4F6 之間的一個碼位。
  4. 完全照樣複製符號串流,不要多加空白、換行、標點符號或變體選擇器。
  5. 若要反向操作,切換到「Base100 to text」,貼上未經修改的符號串流,再執行解碼器。
  6. 若有任何符號落在 256 碼位範圍之外,或產生的位元組不是有效的 UTF-8 序列,解碼器會直接拒絕輸入,而不會產出部分正確的結果。

為什麼符號數量不等於字元數量

只看輸入文字的讀者常常會預期每個輸入字元對應到一個 Base100 符號。這個預期只對純 ASCII 文字成立,因為每個 ASCII 字元只佔一個 UTF-8 位元組。一旦輸入含有非 ASCII 字元,位元組數就會增加,符號數也會跟著增加。為了把規則說明得更具體,讓我們逐步看過 "café" 這個四個字元的單字:

  • "c" → byte 99 (0x63)
  • "a" → byte 97 (0x61)
  • "f" → byte 102 (0x66)
  • "é" (Unicode U+00E9) → UTF-8 bytes 195 (0xC3) 和 169 (0xA9)

四個輸入字元因此變成五個 UTF-8 位元組,Base100 編碼器對這個輸入就會回傳五個符號。當來源文字中含有帶重音字母、CJK 字元或表情符號時,也會發生同樣的膨脹現象,因為每個落在 ASCII 之外的 Unicode 碼位會使用兩到四個 UTF-8 位元組。因此編碼器測量的是編碼後的位元組,而不是使用者感知的字元、字形簇、單字或原始的 JavaScript 字串長度。這是在比較來源字串長度與編碼輸出長度時常見的混淆來源,也是任何 Base100 編碼範例中最明顯的副作用之一。

限制、錯誤與嚴格的解碼器

來自實作的三個限制直接決定了你所能產生的每個 Base100 編碼範例,也說明了為什麼有些貼上的值無法往返轉換。

範圍

解碼器只接受 U+1F3F7 到 U+1F4F6 之間的碼位。其他任何東西 — 空白、換行、變體選擇器、標點符號或被替換掉的字型 — 都會被拒絕,因為這些字元都不是原始格式的一部分。解碼器刻意把它們視為邊框錯誤,而非可以忽略的雜訊。

UTF-8 有效性

從每個碼位減去 U+1F3F7 還原出位元組值之後,解碼器會執行嚴格的 UTF-8 檢查。如果位元組序列不是結構正確的 UTF-8 字串,工具會回報錯誤,而不是悄悄插入替代字元、假裝結果是精確的。WHATWG 編碼標準定義了在文字介面上所使用的 UTF-8 行為。

大小

頁面在任一方向上都把上限設為 500,000 個位元組或符號,避免不小心的巨大貼上讓瀏覽器卡住。空白的輸入會被拒絕,輸出也絕不會被悄悄截斷。獨立的測試資料會鎖定最低與最高的碼位以及具代表性的位元組偏移,這就是實作能保證上表中邊界值的方式。

表情符號的呈現方式會因為作業系統、字型、瀏覽器和訊息平台不同而有所差異。有些對應到的碼位顯示為彩色圖示,有些則是單色字型、方框或出乎意料的圖像。在符合規範的字串中,呈現方式不會改變其數學對應,但若透過會替換、移除或裝飾字元的系統來複製,就可能會改變。在螢幕上看起來與原本完全相同的貼上值,仍可能含有變體選擇器(例如 U+FE0F)、軟連字號或正規化變更,讓嚴格的解碼器拒絕它。當互通性很重要時,請保留完全相同的碼位,因為沒有校驗和可以偵測到意外的變動。

什麼時候其他編碼更合適

Base100 是本站上眾多文字編碼中的一種。下表以質性方式比較使用情境;精確的輸出大小會依輸入而不同,所選的工具會給出你那份資料的精確數字。

需求本站更合適的選擇原因
在會過濾掉表情符號的系統中,僅以 ASCII 傳輸Base64、Base32、Base58 或十六進位編碼器在傳輸、檔案與 API 之間具備廣泛相容性
可還原且具表情符號風格輸出的視覺化展示Base100 編碼器 / 解碼器在剛好 U+1F3F7..U+1F4F6 範圍內,一個位元組對應一個符號
機密性、密碼保護或防竊改AES、HMAC、RSA 或 SHA 工具經過審查的密碼學並具備驗證機制,而非僅是可見的對應
十六進位位元組、二進位位元組或數值碼位十六進位、二進位或 Unicode 碼位轉換器檢視輸入的原始位元組或純量值

Base100 是一種編碼,不是加密、雜湊、簽章、驗證、壓縮、隱寫術或人類語言的表情符號翻譯。任何拿到對應表的人都能還原文字,改動一個符號就會改動一個位元組,而且沒有內建的校驗和可以標示出這個改動。對於密碼、權杖、私鑰或機密訊息,請改用經過審查的加密與驗證格式。如需一份能搭配此逐步範例使用的位元組、表情符號與解碼模式速查表,請參閱 Base100 編碼速查表

若想進一步深入了解,請參閱 Base64 解碼範例:從 'Hello' 到一個表情符號