ROT13 是一種凱薩密碼,會將每個 ASCII 字母在字母表中精確旋轉 13 個位置,由於英文字母表共有 26 個字母,因此對同一個字母套用相同操作兩次會使其回到原始位置。ROT 密碼解碼器利用這個自反性質將打亂的文字還原成可讀的明文——貼上編碼後的文字、執行 ROT13,工具就會產出原始訊息。相同的輸入與相同的按鈕也能將明文編碼成 ROT13,因為這個轉換沒有金鑰、沒有方向旗標,也沒有獨立的解密模式。經典的 ROT13 對應只會影響 26 個大寫 ASCII 字母 A 到 Z 以及 26 個小寫 ASCII 字母 a 到 z,數字、標點符號、變音符號、CJK 字元以及表情符號都不會被動到。這樣狹窄的範圍是刻意設計的:它符合 RFC 1855 中所述 1980 年代 Usenet 公用程式的原始定義,也符合官方 Python rot_13 編解碼器的行為,後者是一種字串對字串的文字轉換,而非具有可調參數的密碼。

ROT13 如何成為自己的解碼器
ROT13 屬於凱薩位移家族,其中每個字母會被替換為字母表中固定距離之外的另一個字母。在位移值為 13 的情況下,26 個字母的英文字母表會整齊地分成兩半:前 13 個字母(A 到 M,以及其對應的小寫形式)對應到後 13 個字母(N 到 Z),而後 13 個字母則對應回前 13 個。執行一次轉換後,A 變成 N,N 變成 A,M 變成 Z,Z 變成 M。再對 N 執行一次會還原回 A;對 Z 再執行一次會還原回 M。由於每個字母都會落在字母表的另一半,沒有任何字母在單次套用時會對應到自己,也沒有任何字母會被困在多步循環中。其數學形式就是 (碼點 − 基準值) + 13 mod 26 + 基準值,其中大寫字母的基準值為 65,小寫字母為 97,與 CPython encodings/rot_13.py 原始碼中的參考實作一致。
這樣的代數特性對任何搜尋「rot 密碼解碼器」的人有一個實際意涵:它沒有獨立的解碼模式。前進與反向是同一個按鈕。看到「Jung nynf lbh unir jrnevat」這種打亂片語的讀者,可以把它貼到 ROT13 編碼解碼器中,套用一次 ROT13,就能讀出「What alas you have wearing」——完全不需要知道原始的位移值或設定任何金鑰。從一般英文開始的讀者,只要執行一次 ROT13,就會得到寄件者可能已在網路上貼出的同一種打亂形式。這就是這個密碼的全部用途,同時也是它唯一的保護:任何認出 ROT13 的人都能立刻還原它。
三步驟向前或反向執行 ROT13
- 貼上你的文字。將 ASCII 字母、數字、標點符號、變音符號或表情符號等任意混合內容拖入輸入區域。該工具在單次貼上中最多接受 1,000,000 個 UTF-16 碼元;剛好達到上限的文字會被完整轉換,超過上限一個碼元的內容會在任何轉換執行之前被拒絕並顯示明確訊息。空白的輸入同樣會被拒絕,而只包含非字母字元的貼上屬於有效輸入,產生的字母變更數為零。
- 套用 ROT13 並讀取結果。按下按鈕,將每個 ASCII A–Z 與 a–z 的字母位移 13 個位置,同時保留所有其他碼元不變。輸出面板會顯示轉換後的字串以及被變更的 ASCII 字母數量。由於每個符合條件的字母必定會被替換為另一個字母,回報的數量同時也是數值發生變化的碼元位置數,數字、空格與 Unicode 字元都不會讓這個數字膨脹。
- 複製輸出,或再次執行 ROT13。使用複製控制項將結果放到剪貼簿,若剪貼簿權限被拒絕,則隨時可以手動選取唯讀輸出。若要還原原始文字,請將 ROT13 的輸出再次貼回輸入欄,並第二次套用 ROT13——自反性質保證會精確還原出原始字串,包括第一次未動到的所有字元。
哪些字元會變,哪些保持不變
ROT13 轉換刻意只作用於一組狹窄的碼元。下表整理了各字母表中具代表性字母的官方對應關係,與 Python rot_13 編解碼器原始碼所描述的行為一致。
| 輸入 | ROT13 輸出 | 說明 |
|---|---|---|
| A | N | 前半段 → 後半段 |
| M | Z | 前半段結尾 |
| N | A | 後半段 → 前半段 |
| Z | M | 最後一個字母繞回 M |
| a | n | 小寫獨立對應 |
| n | a | 小寫鏡像 |
| z | m | 最後一個小寫字母 |
| é, ç, ø, Ж, 漢, 🙂 | é, ç, ø, Ж, 漢, 🙂 | 非 ASCII A–Z / a–z——保持不變 |
| 0–9, 空格, Tab, NUL | 0–9, 空格, Tab, NUL | 非 ASCII 字母——保持不變 |
這個狹窄的對應帶來兩個讀者應該預期到的實際效果。第一,輸出的長度在 UTF-16 碼元數上永遠等於輸入的長度,因為每個被轉換的 ASCII 碼元會被精確替換為另一個 ASCII 碼元,而所有其他碼元都會原封不動——編碼輔助字元(表情符號、少見的 CJK 表意文字)的代理對會以各兩個碼元的形式完整存活。第二,混合語言的文字行為是可預期的:字串 "café" 會變成 "pnsé",因為 c、a 與 f 是 ASCII 字母,而 é 不是;而像字母 e 後接 U+0301 這種組合序列,則只會改變 ASCII 的 e,組合用的尖音符保持不變。這種嚴格的、僅限 ASCII 的行為,正是官方 Python 編解碼器所定義的內容,也正是 ROT13 編碼解碼器所重現的行為——沒有依地區語言的替換、沒有大小寫轉換、沒有 Unicode 轉寫。
ROT13 與 ROT5、ROT18、ROT47 的比較
ROT13 是網路論壇、搶旗賽(CTF)挑戰與日常混淆工具裡流傳的數種「ROT」密碼之一。這個產品合約明確排除了相關變體,因此讀者在按下錯誤的按鈕之前,應該先了解每種密碼各自的用途。
| 變體 | 作用範圍 | 位移 | 本站是否實作? |
|---|---|---|---|
| ROT5 | ASCII 數字 0–9 | 5 | 否——不會轉換字母 |
| ROT13 | ASCII A–Z 與 a–z | 13 | 是——主要行為 |
| ROT18 | ASCII 字母 + 數字 | 字母 13、數字 5 | 否——不會轉換數字 |
| ROT47 | 可列印 ASCII(! 到 ~) | 47 | 否——使用不同的碼元範圍 |
| 任意凱薩位移 | ASCII A–Z 與 a–z | 0–25 的任意值 | 否——僅固定位移 13 |
ROT13 僅限字母的特性正是它自反的原因:13 剛好是 26 的一半,所以套用兩次會互相抵消。ROT5(僅限數字)因為同樣的理由也是自反的——5 是 10 的一半——但它完全不會動到字母,所以對同時混用字母與數字的文字沒有幫助。ROT18 是 ROT13 與 ROT5 的組合,有時被描述為涵蓋 36 個符號字母表的兩半,不過只有當兩半各自獨立套用時,它才共享 ROT13 的自反性質。ROT47 則是將所有 94 個可列印符號位移 47 個位置,它在自己的 94 符號集合上同樣是自反的,但套用於一般英文單字只會產生無意義的結果。對於需要跨字母、數字或整個可列印 ASCII 範圍進行可設定位移的情境,凱薩密碼工具或ROT47 編碼解碼器涵蓋了這些相鄰的使用情境。
ROT13 不是加密——它的真正用途是什麼
ROT13 沒有秘密金鑰。替換表是公開的,對每個寄件者與每位讀者完全相同,任何認出這個模式的人都能立即還原。這代表 ROT13 提供零機密性、零身分驗證、零完整性保護,也無法抵擋自動化攻擊——它是任何人都能在腦中或用一行腳本套用的固定替換。依據 Python codecs 文件,rot_13 被登記為字串對字串的文字轉換,與大小寫轉換或 HTML 跳脫屬於同一類別,而非密碼學原語。請把 ROT13 視為一種混淆,概念上等同於全部大寫或反轉句子,絕對不要用它來保護密碼、權杖、私訊、API 金鑰或正式環境設定。
ROT13 真正有用的情境,與它從早期 Usenet 時代以來一直在處理的工作相同:在明顯處藏起劇透,讓隨意瀏覽的讀者不會不小心看到劇情細節;在解碼前先遮蔽謎題答案、笑話或不雅內容;產生用於測試字母替換程式碼的測試資料;在教學情境中展示凱薩位移的運作原理;以及輕度遮罩應被操作員看到、但不應被搜尋引擎檢索的日誌行或錯誤訊息。在這些情境中,價值在於人為的判斷而非安全性:讀者必須主動執行 ROT13 才能看到內容,而任何主動執行它的人都能看到內容。當機密性很重要時,請把 ROT13 與真正的密碼學系統搭配;對任何需要保持私密的內容,請使用本機產生的強密碼以及經過稽核的認證加密。
最後,在瀏覽器中執行 ROT 密碼解碼器時,有兩個小但重要的行為值得注意。第一,工具在當前分頁中處理所有內容——沒有任何輸入、輸出或剪貼簿內容會被上傳到伺服器——這對於不想留在第三方服務的日常文字來說是正確的模型。第二,這個操作在寬鬆意義下具有等冪性:重複執行不會累積偏差——貼上 "Hello",得到 "Uryyb";貼上 "Uryyb",得到 "Hello"。這個往返特性,再加上 ASCII 字母數量永遠等於可見變化的碼元數,使得在手工處理短訊息時,可以輕鬆用肉眼驗證結果。
如果你正在權衡選項,如何解密 Hill 密碼:實例演練對此有詳細說明。
如果你正在權衡選項,使用 ROT47 編碼解碼器時應避免的錯誤對此有詳細說明。