把文字轉成 binary,就是將每個字元對應到它的 Unicode code point,用 UTF-8(或 ASCII 基本範圍)將 code point 編碼為 byte,再把每個 byte 寫成 8-bit 的 binary 字串。ASCII 可列印字元(code point 32–126)的轉換就是單純的十進位轉二進位。超出這個範圍,UTF-8 會疊加多 byte 編碼。搞不清楚自己在哪一層的時候,除錯時間會暴增。
轉換演算法的運作方式
文字轉 binary 的流程分成幾個階段:
- 每個字元都有一個 Unicode code point。ASCII 的 code point 0–127 與 1963 年的原始標準逐 byte 對應。
- Code point 再轉成 UTF-8 byte。0–127 編碼為單一 byte;128–2047 兩個 byte;2048–65535 三個 byte;補充平面(65536–1114111)四個 byte。
- 最後把每個 byte 寫成 8-bit 的 binary 字串,左邊補零。byte 值 65 就變成
01000001。
只處理 ASCII payload 的開發者通常在第 1 步就停了,直接把 ASCII 十進位值當作要轉換的數字。全 ASCII 的情境下確實沒問題,但混入一個非 ASCII 字元,byte 序列就會和單 byte 的天真假設產生偏差。
ASCII 速查表
開發者日常最常碰到的字元是變數名稱、JSON key、HTTP header,其實不需要完整的 ASCII 表。以下子集涵蓋了最重要的範圍:
| 範圍 | 字元 | Code Point | Binary(首 / 末) |
|---|---|---|---|
| 大寫字母 | A – Z | 65 – 90 | 01000001 / 01011010 |
| 小寫字母 | a – z | 97 – 122 | 01100001 / 01111010 |
| 數字 | 0 – 9 | 48 – 57 | 00110000 / 00111001 |
| 空格 | (空格) | 32 | 00100000 |
| 常見標點 | ! " # $ % & ' ( ) * + , - . / | 33 – 47 | 00100001 / 00101111 |
| 冒號到 @ | : ; < = > ? @ | 58 – 64 | 00111010 / 01000000 |
| 括號與反引號 | [ \ ] ^ _ ` | 91 – 96 | 01011011 / 01100000 |
| 大括號與波浪號 | { | } ~ | 123 – 126 | 01111011 / 01111110 |
大寫和小寫之間的差距(65–90 vs. 97–122)剛好是 32,也正好是空格的 code point。切換第 5 個 bit 就能在大小寫之間翻轉,這在 bitwise 操作和某些編碼技巧中會用到。
每個開發者都該知道的 ASCII 邊界情況
有幾個字元範圍在實務中造成的困惑遠超預期。
控制字元(code point 0–31 和 127)是不可列印的。Tab 是 9(00001001),換行 LF 是 10(00001010),回車 CR 是 13(00001101)。Windows 的換行符是 CRLF,兩個 byte,不是一個。如果在 binary dump 中看到可列印字元之間出現不明 byte,幾乎都是這幾個控制字元。
Code point 127(01111111)的 DEL 字元也不可列印。它是最後一個單 byte ASCII 值,也是 7-bit 範圍內最大的 code point。某些老系統會把它誤判為高值的可列印字元。
Extended ASCII(128–255)才是真正混亂的開始。嚴格來說 ASCII 只到 127。128–255 的 code point 在 UTF-8 統一天下之前,被幾十種互相競爭的標準搶著用(ISO-8859-1、Windows-1252 等等)。一個值為 130(10000010)的 byte,在不同編碼下代表完全不同的字元,這是老資料庫和 email 系統中 mojibake 最常見的來源。
UTF-8 多 byte 序列遵循一套前綴規則:以 110xxxxx 開頭的 byte 表示 2-byte 序列,1110xxxx 表示 3 byte,11110xxx 表示 4 byte。接續 byte 都以 10xxxxxx 開頭。像 11000011 後面接 10000000,這是一個 2-byte 序列,編碼的是 U+00C0(À),不是兩個獨立的字元。
開發過程中想快速驗證,免費的文字轉 Binary 線上轉換器可以處理完整的 UTF-8 編碼,不需要自己寫腳本。要在接上 parser 之前確認某個字串會產生哪些 byte 時特別好用。
從 Binary 轉回文字
解碼就是把步驟反過來:把 binary 字串切成 8-bit 一組,每組從 binary 轉成十進位,查出 Unicode code point,再解碼 UTF-8 多 byte 序列。
容易出問題的地方:以空格或固定寬度分組的方式假設每個字元都是 8 bit。如果收到的 binary 沒有間隔,你必須事先知道編碼方式,才能判斷一個字元在哪裡結束、下一個從哪裡開始。UTF-8 的自同步設計(接續 byte 一律以 10 開頭)讓你在遇到損壞的 byte 後能重新對齊,但前提是你得知道自己在讀 UTF-8。
開發者工具中 binary 輸出錯誤最常見的原因,就是編碼端和解碼端的編碼假設不一致:一邊把字串當成 Latin-1,另一邊當成 UTF-8。byte 是一樣的,但解讀方式不同。
實際應用場景
協定除錯時,Wireshark、tcpdump 和 hex editor 都在 byte 層級顯示資料。知道預期字串的 binary 或 hex 值,就能在原始封包中直接定位 payload。
CTF 挑戰中 binary 編碼的文字經常出現,可能是完整的 8-bit binary 字串,也可能是等效的 hex。記住 ASCII 範圍(65–90 大寫、97–122 小寫)能快速縮小候選字元集。
程式裡做 bitwise 運算的時候,位移運算子、AND/OR/XOR 遮罩、bit-field 擷取都需要你清楚值的 binary 佈局。用 bitmask 對字元分類的字串處理,例如判斷一個 byte 是否為可列印 ASCII,直接仰賴這些知識。
編碼驗證也是常見場景。資料庫存入文字後取出的卻是亂碼,問題幾乎都出在寫入時用的編碼和讀取時假設的編碼不一致。用已知的測試字串檢查 binary 輸出,就能確認實際使用的是哪種編碼。
FAQ
手動把字母轉成 binary 最快的方法是什麼?
查出該字元的 ASCII 十進位值,再把那個數字轉成 8-bit binary。大寫 A–Z 的 code point 是 65–90,小寫 a–z 是 97–122。記得每個 bit 的權重(128、64、32、16、8、4、2、1),小數字的轉換不到 30 秒就能算完。超過幾個字元的話,直接用轉換工具比較實際。
文字轉 binary 一定是用 ASCII 嗎?
不一定。ASCII 只涵蓋 code point 0–127。文字一旦包含重音字母、非拉丁文字、emoji 或超出此範圍的貨幣符號,UTF-8 會產生多 byte 序列,binary 輸出會超過每個字元 8 bit。現代系統預設用 UTF-8,所以只有在你確認字串中沒有超過 code point 127 的字元時,才能放心假設是純 ASCII。
為什麼同一個字元在不同工具中會產生不同的 binary 輸出?
工具之間可能在編碼(UTF-8 vs. Latin-1 vs. UTF-16)、byte 順序(big-endian vs. little-endian)或輸出格式(以空格分隔的 8-bit 群組 vs. 連續的 bit 字串)上有差異。單 byte 的 ASCII 字元各工具輸出一致,差異會在輸入包含 extended 字元、或工具沒有標明使用哪種編碼時浮現。