文字隱寫術(Text steganography)是將秘密訊息藏在外觀普通的文字中的做法,讓任何快速瀏覽檔案的人只會看到掩護句子,而看不到隱藏的酬載。這個技巧仰賴大多數字型以零寬度方式呈現的 Unicode 碼位——這些字元可以貼上和複製,但在頁面上不會佔用任何可見空間。像 Text Steganography 這種適合初學者的工具遵循一套明確的慣例:將你秘密訊息的每個 UTF-8 位元組轉成八個不可見的位元,再用兩個不可見的標記字元框住這些位元,然後把整個框住的序列悄悄塞進掩護文字的第一個可見碼位之後。當接收者把結果貼到解碼模式時,工具會讀取標記、驗證每個酬載字元都是 0 位元或 1 位元、檢查位元數是否為 8 的倍數,然後把位元解碼回原本的 UTF-8 位元組。沒有任何資料會被上傳——編碼與解碼完全在瀏覽器中執行,因此掩護文字與秘密訊息都不會離開你的裝置。

文字隱寫術的運作原理(白話版)
隱寫術不同於密碼學。密碼學是將訊息打亂,讓攔截者無法讀取;隱寫術則是隱藏「有秘密存在」這件事本身。文字隱寫術把這個概念套用到一般字元上:一個可見的掩護句子承載著隱藏的酬載,而酬載是由任何普通字型都不會在螢幕上顯示的 Unicode 碼位所組成。
這個工具所使用的慣例刻意設計成可檢驗的。一切工作由四個碼位完成:
- 零寬度空格(U+200B)代表二進位 0。
- 零寬度非接合符(U+200C)代表二進位 1。
- 一個不可見分隔符(U+2063)標記酬載的開頭。
- 一個不可見加號(U+2064)標記酬載的結尾。
你秘密訊息的每個 UTF-8 位元組會剛好變成八個不可見的位元,以最高有效位元優先的方式寫入。框住的序列——開始標記、位元、結束標記——會插入掩護文字的第一個可見碼位之後,因此該字串仍以讀者預期的同一個碼位開頭。
零寬度的基礎元件
你不需要記住這些碼位就能使用這個工具,但了解它們的存在能讓輸出結果不再那麼神祕。這些字元都是標準 Unicode 的一部分,這代表任何現代的文字編輯器都能儲存並複製它們。它們的共通點是一個稱為「預設可忽略」(default ignorable)的特性:大多數渲染引擎在計算行寬時會略過它們。
這個特性正是文字隱寫術得以成立的關鍵。因為字型不會給予它們任何前進寬度,掩護句子能維持原本的換行與縮排;因為它們是真實的碼位,所以能在任何忠實處理 Unicode 的系統中透過複製貼上存活下來;因為肉眼看不出來,所以只有知道要去找的人——或是把文字跑過字元計數器或碼位檢視器的人——才會察覺其中藏有東西。
這個慣例把所有碼位都明確標示出來的設計選擇,也意味著整個轉換是完全可逆的。只要框住的部分在傳輸過程中保留下來,當初藏入訊息的同一個工具就能夠逐位元組地把訊息再取出來。
一步步藏入你的第一則訊息
這個演練使用一段簡短的秘密訊息,讓你可以一眼看清整個來回流程。在瀏覽器中開啟工具——無需安裝、無需帳號、無需上傳。
- 在掩護文字欄位中,輸入一句你不介意任何人看到的普通句子,例如「Meet me at the library after lunch.」。
- 在隱藏訊息欄位中,輸入你真正想傳送的秘密。一開始先保持簡短;單字或簡短片語較容易驗證。例如:「2pm」。
- 點擊動作按鈕以產生隱寫字串。可見的輸出在你眼中仍然會讀作「Meet me at the library after lunch.」,但其底層的碼位序列會比你輸入的句子長得多。
- 使用複製按鈕取得精確的結果。不要用手重新輸入——不可見字元很容易被漏掉,少一個位元就可能毀損酬載。
- 透過你預計使用的管道(電子郵件草稿、聊天訊息、本機文字檔)把複製好的字串傳給自己,並在信任該管道承載任何敏感資料之前,先貼回解碼模式做一次來回測試。
掩護文字上限為 100,000 個碼位,隱藏訊息上限為 10,000 個 UTF-8 位元組,因此即使是相當長的秘密訊息也能從容容納。
完整範例:假設你的秘密訊息是兩個字母「Hi」。「H」是 U+0048;在 UTF-8 中它是單一位元組 0x48,二進位表示為 01001000。「i」是 U+0069;在 UTF-8 中它是 0x69,二進位表示為 01101001。整段秘密訊息合計為 2 位元組 × 8 位元 = 16 個不可見碼位,再加上首尾各一個標記。十六個不可見字元數量很小,如果你想確認工具實際產生了什麼,可以用 Unicode 檢視器手動檢查。
解讀你收到的訊息
解碼模式是相反的動作。你不需要重新輸入原本的掩護文字,也不需要記得秘密訊息——框住的序列本身就帶有還原兩者所需的全部資訊。
- 把你收到的完整隱寫字串原封不動地貼到解碼模式。不要清理它、不要用「移除格式」工具處理,也不要重新調整換行。
- 觸發解碼動作。工具會尋找開始標記(U+2063)與結束標記(U+2064),然後驗證它們之間的每個酬載字元不是 U+200B 就是 U+200C。
- 如果位元數是 8 的倍數且位元解碼後是有效的 UTF-8,工具就會回傳隱藏的訊息。它也會回傳可見的掩護文字,也就是從原始字串中移除框住序列後重建出來的內容。
- 如果任何步驟失敗——缺少標記、出現非預期字元、位元數不是 8 的倍數,或位元組無法組成有效的 UTF-8——工具會將其視為錯誤,而不是去猜測。這種嚴格的行為正是讓來回傳輸值得信賴的原因。
為什麼訊息有時會在傳輸過程中消失
初學者最常遇到的意外,是在另一端打開訊息時卻發現什麼都沒有。工具並沒有出問題;而是傳輸過程中有某個環節把不可見字元給剝掉了。
許多系統會在幕後對文字進行標準化或過濾。社群網路、電子郵件閘道、聊天用戶端、內容管理系統以及剪貼簿管理員,都可能把預設可忽略的碼位當作不存在、替換行尾符號,或直接拒絕標記碼位。螢幕截圖與列印副本根本無法承載不可見的碼位——PNG 是像素的圖片,而像素並不會編碼 U+200B。
這就是為什麼文件會警告你只能透過已端對端測試過的管道來複製產生的字串。一個能精確保留 Unicode 的純文字編輯器(例如以支援 Unicode 的編輯器開啟的本機 .txt 檔),比起會清理貼上內容的網頁表單,更有可能讓酬載完好無損地保存下來。如果傳輸後解碼失敗,可以比較兩端的原始碼位,找出是哪個應用程式移除了或變更了不可見字元。
Unicode Security Considerations 報告在更廣泛的脈絡下討論了許多相同的清理風險,包括為什麼預設可忽略的碼位往往是從惡意輸入中第一個被過濾掉的對象。
隱寫術 vs 密碼學:搞懂差異
許多初學者指南都會混淆這兩個詞,在把真實資料交給任何隱寫工具之前,值得先把這個混淆釐清。
| 特性 | 文字隱寫術(本工具) | 傳統密碼學 |
|---|---|---|
| 可見輸出 | 看起來與掩護句子一模一樣 | 看起來像亂碼文字 |
| 它隱藏的東西 | 秘密的存在 | 秘密的內容 |
| 機密性 | 無——任何知道慣例的人都能解碼 | 當演算法與金鑰可靠時,具有高度機密性 |
| 完整性/真實性 | 無——任何人都能編輯酬載 | 經認證的模式可同時提供兩者 |
| 典型用途 | 展示、謎題、清理器測試、學習 | 保護傳輸中的憑證、訊息與檔案 |
如果你需要隱藏憑證、具傷害性的指示、個人資料,或任何違反平台規範的內容,請先使用經過審核的系統進行加密,再透過任何你喜歡的管道傳輸密文。隱寫術本身只是隱匿,並非機密性。
你需要知道的限制、標記與碼位
這些數字直接來自工具的說明文件行為,讓你可以預先規劃,而不是透過反覆嘗試才發現。
| 項目 | 數值 |
|---|---|
| 隱藏訊息上限 | 10,000 UTF-8 位元組 |
| 掩護文字上限 | 100,000 個碼位 |
| 每個隱藏位元組的位元數 | 8(一個位元組變成八個不可見字元) |
| 二進位 0 符號 | U+200B 零寬度空格 |
| 二進位 1 符號 | U+200C 零寬度非接合符 |
| 開始標記 | U+2063 不可見分隔符 |
| 結束標記 | U+2064 不可見加號 |
| 框住序列的位置 | 緊接在掩護文字的第一個可見碼位之後 |
| 處理位置 | 僅在瀏覽器中——沒有任何資料會被上傳 |
因為每個隱藏的位元組會變成八個額外的碼位,再加上兩個標記,所以 10,000 位元組的酬載會在你的檔案中增加大約 80,002 個不可見字元。這也是掩護文字上限存在的原因——讓總碼位數可預測,才能維持頁面的回應速度。表情符號與非拉丁文字通常各佔用超過一個 UTF-8 位元組,因此你在編輯器中看到的隱藏「字元數」往往小於你實際消耗的位元組預算。
另一個值得記住的限制:掩護文字中不能已經包含本慣例的開始或結束標記。如果包含了,工具會拒絕處理,因為接受既有的標記會讓酬載邊界變得模糊不清。然而,位於框住區域之外的一般零寬度字元仍屬於可見掩護文字的一部分,會原封不動地保留下來。
Quick Checks Before You Trust a Result
A short checklist is the easiest way to avoid the beginner traps.
- Run a self-test before you send anything important: hide a message, copy it, paste it back into reveal mode, and confirm both the hidden text and the recovered cover match what you typed.
- Pick the transport channel first and prove it carries invisible characters with a tiny test payload — even a one-letter secret is enough to verify the round trip.
- Remember that "the visible sentence looks the same" does not mean "the file is unchanged." The code-point sequence is much longer after embedding, and a character counter or a diff tool will reveal the extra characters immediately. That is fine if your audience is a puzzle solver; it is a problem if your audience is a security scanner.
- Keep the use case modest. Text steganography is great for learning how Unicode can carry non-rendering data, for harmless puzzles, and for testing how a sanitizer handles invisible input. It is not a substitute for encryption and it is not a reliable way to bypass a platform's content rules.
For readers who want the long-form reference — every code point, every limit, and a copyable step list — the Text Steganography Cheat Sheet: Codes, Limits, Steps collects the same facts in one place.
If you're weighing options, Text to Binary in Python: Byte-Exact UTF-8 in Practice covers this in detail.