手動將文字轉成二進位表示將 Unicode 字串的每個 UTF-8 位元組寫成正好八個二進位數字,並以單一空格分隔。若要手動將文字轉成二進位,請先寫下每個字元的 UTF-8 位元組序列,再將每個位元組展開為八位元、補零的位元。字母 H 會變成 01001000,因為它的 ASCII 碼是 72,而 72 的二進位是 1001000。帶重音的字母(例如 é)佔用兩個 UTF-8 位元組(11000011 10101001),歐元符號 € 佔用三個(11100010 10000010 10101100),而補充字元例如笑臉表情符號 😀 則佔用四個位元組。在手動轉換中,沒有標明編碼是造成結果不一致最常見的原因:某個工具將 é 視為單一 16 位元的 Unicode 程式碼單元,另一個將它視為兩個位元組,還有一個在解碼器失敗時會靜默替換成 Unicode 替換字元。因此,位元組完全一致的手動轉換必須遵守三條不可妥協的規則:選擇 UTF-8、將輸出嚴格分成八位元一組並以一個普通空格分隔,以及當序列格式錯誤時絕不補位、修剪或猜測。

how to convert text to binary manually
如何手動逐位元組將文字轉換為二進位

為手動轉換選擇 UTF-8

UTF-8 是定義每個 Unicode 碼點如何對應到一至四位元組特定序列的編碼標準。WHATWG 編碼標準定義了所有現代瀏覽器使用的規則,而 Unicode 標準則定義了 UTF-8 所對應的碼點。當你手動將文字轉成二進位時,其實是在回答兩個問題:你選了哪一種編碼,以及你要輸出哪些單位。對於網頁、原始碼檔案或 JSON 酬載,誠實的答案永遠是 UTF-8 位元組,因為 UTF-8 是幾乎所有通訊協定實際傳遞的線路格式。

如果你跳過編碼問題,直接將每個字元的數值以二進位寫下,得到的結果看起來像二進位,卻不是位元組。字母 A 作為 Unicode 碼點是 U+0041,將該純量值以二進位表示會得到 1000001,只有七位數。多數讀者會將它補成 01000001 以維持每組八位元,但這只是呈現上的選擇,並非網路傳輸的事實。一旦輸入包含 é(U+00E9),以碼點二進位表示的方法會產生一個 16 位元的字串,與伺服器實際送出的位元組不符。這兩種方法只有在 ASCII 範圍內才會一致,這也是為什麼初學者常以為自己的手動方法是正確的,直到測試了非 ASCII 的詞彙才發現問題。

手動轉換單一字元

你可以練習的最小單位是單一 ASCII 字母,因為 ASCII 在 UTF-8 中以單一位元組表示。選 H。查詢它的 ASCII 碼,是 72。將 72 透過減去可容納的最大 2 的冪次來轉成二進位:72 減 64 剩 8,8 減 8 剩 0,你使用的 2 的冪次是 64 與 8,對應的位元位於第 6 位與第 3 位。從位元 7 往下讀到位元 0,得到 01001000。在左側補零,使該組正好八位數,而 H 的二進位就是 01001000。整個計算過程,以重複除以二的方式寫出來如下:

72 ÷ 2 = 36 餘 0 36 ÷ 2 = 18 餘 0 18 ÷ 2 = 9 餘 0 9 ÷ 2 = 4 餘 1 4 ÷ 2 = 2 餘 0 2 ÷ 2 = 1 餘 0 1 ÷ 2 = 0 餘 1 由下往上讀取餘數:1001000。 補零至 8 位元:01001000。

這單一一組就是嚴格的轉換器對 H 所產生的結果。對較長字串的每個位元組重複同樣的除以二程序,就完成了手動的二進位編碼。機械性的部分很簡單;會出錯的部分在於當輸入離開 ASCII 範圍時,什麼才算是一個位元組。

將完整字串轉換為二進位

若要手動將任何超過單一字母的文字轉成二進位,請依照以下精確步驟:

  1. 決定使用 UTF-8 作為編碼。使用其他編碼會導致位元組數與伺服器、檔案或 JSON 解析器實際承載的內容不符。
  2. 取得該字串的 UTF-8 位元組序列。你可以從 ASCII 表查詢字母與數字,從 UTF-8 對照表查詢帶重音字元,或使用符合標準的編碼器取得。
  3. 對於序列中的每個位元組,使用重複除以二的方式將該位元組的十進位值(0 到 255)轉成二進位。
  4. 將每個結果寫成正好八個二進位數字,加上前置零,使每組始終為八位元寬。
  5. 以單一普通空格分隔各組。不要使用逗號、定位字元、0b 前綴或多個空格。
  6. 計算組數。對於純 ASCII 輸入,位元組數等於字元數;對於其他輸入,位元組數會較大,必須等於每個字元 UTF-8 寬度的總和。
  7. 若某個位元組無法編碼,或來源文字包含無效的代理對,請停止。手動轉換無法還原來源中沒有的資訊。

第五個步驟是多數人會跳過的一步。他們用隨手可得的字元連接各組,之後才納悶為何解碼器稍後拒絕接受結果。嚴格的八位元一組、以恰好一個空格分隔,是所有位元組完全精確的反向工具都能接受的格式,包括文字轉二進位轉換器。

每個字元實際使用的位元組數

UTF-8 是一種可變寬度的編碼。字元的位元組數取決於其所屬的 Unicode 範圍,而非它在視覺上看起來像幾個符號。下表的寬度由 Unicode 標準定義,並與瀏覽器的 TextEncoder對各類輸入所產生的結果一致。

字元類別範例UTF-8 位元組數
ASCII 字母或數字A, 71 位元組
帶重音的拉丁字母é, ñ2 位元組
貨幣符號或符號€3 位元組
CJK 表意文字中,漢3 位元組
補充平面的表情符號😀, 🎉4 位元組

歐元符號使用三個位元組,這讓預期符號與帶重音字母寬度相同的人感到意外。CJK 表意文字與歐元符號在螢幕上看起來截然不同,卻恰好落在同一個三位元組範圍,因為它們的碼點位於基本多語言平面的 U+2000 到 U+FFFF 區段。表情符號則落在該平面之外的補充平面,因此需要四位元組。任何宣稱非 ASCII 輸入為固定「每字元一個位元組」的手動結果都應視為錯誤。

手動轉換結果不一致之處

手動轉換與參考輸出產生差異,通常來自五個可預見的原因。每一項改變的都是位元組本身,而不僅僅是格式。

  • 使用 UTF-16 程式碼單元而非 UTF-8 位元組。JavaScript 字串採用 UTF-16,因此一個快速的 "charCodeAt" 迴圈會產生 16 位元的值,而非位元組。一個補充平面的表情符號會變成一對代理對,所產生的二進位字串便與網路實際傳遞的內容不再一致。
  • 省略了補零。字母 A 為 1000001,只有七位數。若未在左側補零,該組寬度錯誤,嚴格的解碼器會拒絕接收。每一組都必須正好八位數。
  • 列印純量值的二進位而非位元組本身。對於 ASCII 而言兩者恰好相同,因此養成這種習慣;對於 é,純量值為 U+00E9,而位元組為 C3 A9,兩者所得的二進位字串並不一致。
  • 靜默替換無效的位元組。設定為使用替換字元的解碼器會將格式錯誤的輸入悄悄轉為 U+FFFD 而不發出警告。使用者誤以為往返轉換成功,實際上位元組早已遺失。
  • 讓聊天軟體壓縮空格。在原始資料中以一個空格連接各組是可行的,但所見即所得編輯器與聊天應用程式常常會去除或合併連續的空白。一旦分隔符消失,嚴格格式便不復存在,嚴格的解碼器將拒絕輸入。

這五種失敗都源於同一個根本原因:一個本應精確無誤的步驟被當作呈現上的細節來處理。UTF-8 位元組是精確的,手動程序也必須忠於它們。

使用文字轉二進位轉換器取得嚴格的輸出

當手動程序過於冗長,或需要將手動轉換結果與參考值比對時,請使用文字轉二進位轉換器。此工具透過瀏覽器符合標準的 TextEncoder 將 Unicode 文字編碼,並將每個位元組列印為正好八位元、補零的位元,以單一 ASCII 空格分隔,也就是上文所描述的格式。反向模式同樣要求嚴格的格式,並使用嚴格的 UTF-8 解碼器,因此格式錯誤的位元組序列會產生明確的錯誤,而非被悄悄替換為 U+FFFD。八組獨立的黃金測試案例涵蓋 ASCII、一個單字、雙位元組的拉丁文字、三位元組的貨幣符號、四位元組的表情符號、CJK 文字、換行控制位元組,以及混合寬度的字串,皆會與獨立於實作之外所撰寫的預期位元組進行比對。

有幾項實際的限制。編碼端最多接受 20,000 個 UTF-16 程式碼單元,解碼端最多接受 180,000 個輸入字元。解碼器會拒絕諸如 0b 前綴、逗號、定位字元、多個空格、七位元組、九位元組、前後空白,以及任何非 0 或 1 的字元。數值絕不會被補位、修剪、猜測或靜默丟棄。輸入與輸出皆保留在當前的分頁中,不會上傳,因此此工具同樣適用於那些因隱私考量而選擇手動轉換的字串。MDN 文件說明嚴格的 TextDecoder 選項,讓解碼器在遇到無效 UTF-8 時明確失敗,這也正是嚴格格式規則背後的行為基礎。

二進位輸出所包含的資訊與原始文字相同。它是一種可逆的表示方式,並非加密,因此任何收到這些位元組的人都能讀回原始字元。完成轉換後,請僅在能精確保留普通空格與換行內容的系統中複製或儲存結果,例如純文字檔或 Markdown 檔案中的程式碼區塊。聊天軟體與所見即所得編輯器可能會壓縮空格或插入換行,導致稍後的嚴格解碼失敗。若是用於通訊協定、原始碼或鑑識工作,請向目的地系統驗證實際的位元組序列,而非依賴字型對輸出的繪製方式。

相關閱讀:文字轉十六進位範例:UTF-8 位元組在實務中的樣貌。

相關閱讀:解碼 UTF-8 位元組時避免靜默替換字元。