ROT47 不需要獨立的解碼器。這個替換在其 94 個字元的範圍內是自我反函數,這表示用來編碼文字的同一個操作也能用來解碼。可列印 ASCII 正好涵蓋 94 個字碼點,從 33(驚嘆號)到 126(波浪號)。旋轉 47 這個值,正好是 94 的一半,會將每個支援的字元與同一集合中的另一個字元配對。再次套用這個操作會將每個字碼點向前移動 94 個位置,並回到原點。這就是為什麼一個工具搭配一個按鈕就能同時編碼與解碼 ROT47,而不需要金鑰、模式切換或獨立的解碼器頁面。由於同一個動作既能編碼也能解碼,「rot47 需要獨立的解碼器嗎」這個問題的答案很簡單:不需要;貼上、套用、貼上、套用,原文就會回來。

為什麼 ROT47 不需要獨立的解碼器
自我反函數特性的實際結果是,你不必記住字串被編碼過一次還是兩次,也不需要追蹤字母表或密碼。如果結果看起來像是亂碼,把它再貼回同一個欄位,然後再套用一次相同的動作。這個中間字串就會還原成原文。ROT47 編碼解碼器工具直接展現了這個特性:只有一個輸入框、一個「套用 ROT47」動作,沒有獨立的解碼器選項需要選擇。
由於這個操作可以用同一個按鈕反轉,ROT47 與僅處理字母的機制(例如 ROT13 編碼解碼器)不同,後者會將數字與標點符號鎖在原位,只移動英文字母。ROT47 則會旋轉每個可列印 ASCII 字元,包括數字、逗號、括號與符號,這就是為什麼即使逗號或數字緊鄰字母,在輸出中仍然會改變。對於標準的 ROT47 行為,同一個輸入上的同一個按鈕就能處理兩個方向,不需要設定其他任何東西。
ROT47 自我反函數背後的數學
可列印 ASCII 區塊正好包含 94 個字元,佔據從 33 到 126(含)的字碼點範圍。定義 ROT47 的公式如下:
new = 33 + ((value − 33 + 47) mod 94)
當你套用一次 ROT47 時,輸入中每個可列印 ASCII 字元都會在這個 94 字元環中向前移動 47 個位置。當你再次套用時,每個字元會再向前移動 47 個位置,總共移動 94 個位置。由於這個環正好有 94 個位置,94 mod 94 等於 0,因此每個字元都會回到起始字碼點。這個單一觀察就是自我反函數特性的完整證明;不需要獨立的反函數表、金鑰或解碼字母表。透過標準的 codePointAt 操作來迭代 Unicode 字碼點,就足以在任何相容的執行環境中重現這個結果,而可列印區間則是由 Unicode 基本拉丁文圖表所固定。
| 概念 | 數值 | 效果 |
|---|---|---|
| 可列印 ASCII 範圍 | 33 到 126 | 94 個字元在環中旋轉 |
| 旋轉量 | 47 | 正好是 94 的一半 |
| 重複套用 | 47 + 47 = 94 | 將每個字元還原到起點 |
| 空格字碼點 | 32 | 超出範圍,原樣複製 |
| 非 ASCII 字碼點 | 128 及以上 | 複製但不進行正規化 |
如何使用單一工具進行編碼與解碼
- 開啟 ROT47 編碼解碼器頁面,將你想要轉換的精確文字貼到輸入框中。空格、換行以及任何非 ASCII 字元都會原樣保留,所以你不需要跳脫或預先編碼它們。
- 選擇「套用 ROT47」。工具會在同一個欄位中回傳可列印 ASCII 的替換結果,方便複製。可列印 ASCII 範圍內的每個字母、數字、標點符號與符號,都已經在 94 字元環中向前移動了 47 個位置。
- 複製產生的文字。輸出是純文字;如果你打算將它貼到 URL、HTML、shell 指令或正規表示式中,請先跳脫特殊字元,因為標點符號已經被轉換過了。
- 若要解碼,將複製的內容貼回同一個輸入欄位。這個工具不會知道也不在乎字串是否已編碼;它只是對它看到的每個可列印 ASCII 字元套用相同的替換。
- 再次選擇「套用 ROT47」。由於操作具有自我反函數特性,第二次套用會將每個可列印 ASCII 字元還原到原本的字碼點,同時完全不動空格、Tab、換行以及非 ASCII 內容。
如果第二次處理無法還原原文,最可能的原因是某個中介程式竄改了文字:例如聊天客戶端轉換了智慧引號、程式碼編輯器移除了尾端空白、論壇替換了換行符號,或標記語言解讀了 < 或 & 等字元。請用乾淨的副本在原始字串上再套用一次 ROT47。
ROT47 會旋轉哪些字元、會保留哪些字元
會移動的 94 個字元是所有可列印 ASCII 字元:大寫字母 A 到 Z、小寫字母 a 到 z、數字 0 到 9,以及它們之間的所有標點符號與符號,從 ! (33) 到 ~ (126)。不會移動的字元則歸入幾個明確的小類別,因為實作會在不做正規化的情況下,原樣複製 33 到 126 區間之外的每個字碼點。
| 類別 | 字碼點範圍 | 在 ROT47 下的行為 |
|---|---|---|
| 大寫字母 | 65 到 90 | 在 94 字元環中旋轉 |
| 小寫字母 | 97 到 122 | 在 94 字元環中旋轉 |
| 數字 0 到 9 | 48 到 57 | 在 94 字元環中旋轉 |
| 標點符號與符號 | 33 到 47、58 到 64、91 到 96、123 到 126 | 在 94 字元環中旋轉 |
| 空格 | 32 | 原樣複製 |
| Tab、換行、歸位 | 9、10、13 | 原樣複製 |
| 其他控制字元 | 0 到 31、127 | 原樣複製 |
| 帶重音字母 (é, ñ, ü) | 128 及以上 | 原樣複製 |
| CJK 字元、表情符號、符號 | 128 及以上 | 原樣複製 |
邊界正好是低端的字碼點 33 與高端的 126。一個混用 ASCII 單字與帶重音字元或表情符號的句子,只有 ASCII 部分會被轉換;其餘部分會逐字碼點通過,所以表情符號不會被拆成 UTF-16 的兩半,帶重音字母也不會被折疊成 ASCII。
實作範例:編碼 "Hi!"
為了讓公式更具體,編碼三個字元 "H"、"i" 和 "!"。公式為 new = 33 + ((value − 33 + 47) mod 94)。
步驟 1,H 是字碼點 72:new = 33 + ((72 − 33 + 47) mod 94) = 33 + (86 mod 94) = 33 + 86 = 119,也就是字元 "w"。
步驟 2,i 是字碼點 105:new = 33 + ((105 − 33 + 47) mod 94) = 33 + (119 mod 94) = 33 + 25 = 58,也就是 ":"。
步驟 3,! 是字碼點 33:new = 33 + ((33 − 33 + 47) mod 94) = 33 + (47 mod 94) = 33 + 47 = 80,也就是 "P"。
因此編碼後的字串是 "w:P"。若要解碼,對每個字元套用相同的公式:"w" (119) 變成 72 (H),":" (58) 變成 105 (i),"P" (80) 變成 33 (!)。每個可列印 ASCII 字元都繞環移動了 94 個位置,並正好回到起點,而 33 到 126 區間之外的字元完全不會被動到。這就是 ROT47 編碼解碼器在瀏覽器中執行的同一套算術。
ROT47 何時有用、何時沒用
ROT47 對於可逆的情境很有用,目標是讓一個詞組變得沒有那麼一眼可讀,但又不想動用到金鑰。常見的應用包括在論壇文章中輕度遮蔽劇透、在課堂上展示替代式密碼、以編碼本身作為噱頭的解謎遊戲,以及測試字元處理管線,確認標點、數字與符號能正確往返。由於操作是對稱且自我反函數的,它特別適合需要還原轉換、卻不想另外保存解碼程式的人。
當機密性很重要時,ROT47 就是錯誤的選擇。它沒有金鑰、沒有密碼、也沒有隱藏狀態;任何認出這個模式的讀者,只要套用相同的旋轉就能還原編碼。它不提供機密性、不提供完整性、不提供驗證,也不抵抗頻率分析。請把它當成謎題式編碼,而不是安全基元,絕對不要用它來保護憑證、個人資訊,或任何你不想公開張貼的訊息。如果你的目標是真正的機密性,應該使用搭配真正金鑰(在訊息之外管理)的已驗證密碼。
驗證還原結果與處理常見陷阱
由於轉換是確定性且保留位置的,你可以快速判斷解碼後的字串是否正確。計算可疑輸出中可列印 ASCII 字元的數量,並與已知明文的數量比較;兩者必須相符。確認每個非 ASCII 段落都原樣存活。如果你看到智慧型彎引號取代了應該存在的直引號、換行遺失,或空白被修剪,這種損壞是發生在傳輸過程中,而不是 ROT47 步驟內部。請用編碼字串的乾淨副本再套用一次 ROT47,結果應該會與原始字串完全相符。
非 ASCII 內容也具有相同特性。一個表情符號在編碼後與解碼後看起來都完整無缺,這表示實作是逐字碼點迭代,而不是按位元組的兩半處理,同時也代表補充字元沒有被拆開。空白的輸入會被拒絕,所以工具回傳空結果代表你其實沒有貼上任何字元。輸入上限為 200,000 個 Unicode 字碼點,這是唯一的硬性上限;如果你的貼上內容更長,請分成多個區塊,分別對每個區塊套用 ROT47,因為每個區塊都會獨立編碼或解碼,並產生同樣可逆的結果。
如果你正在權衡選項,如何使用 mod 26 反矩陣解密 2x2 Hill 密碼對此有詳細說明。
如果你正在權衡選項,如何使用 HTML 實體編碼解碼器對此有詳細說明。