柵欄密碼解碼器透過重建編碼器所使用的相同列模式、依欄杆長度切片密文,並以每個原始位置一個字元的方式回填每一列,來反轉古典的之字形換位。因為 Rail Fence 從不替換字母,解碼器唯一的工作就是還原編碼器重新排列的每個碼位(無論是字母、數字、空格、標點符號或表情符號)的確切順序。本文所介紹的Rail Fence 密碼解碼器接受 2 到 100 之間的整數欄杆數,並在瀏覽器中本機雙向運行。對於任何確定性的換位來說,一次成功的來回操作(以相同的欄杆數先編碼再解碼)能證明約定相符,但無法證明任何保密性,因為 Rail Fence 中唯一的秘密就是那個小的欄杆數本身。本文其餘部分將逐步說明之字形背後的數學、導致不同實作產生歧異的約定,以及在自己的文字上執行解碼器的確切步驟。

Rail Fence 是換位而非替換
柵欄密碼是一種古典的換位密碼。每個字元(無論是大寫字母、小寫字母、數字、空白字元、標點符號或表情符號)在密文中恰好出現一次,只是位置與明文不同。像 Caesar 或 ROT13 這類替換密碼會把每個字母換成另一個字母,因此可見的字母表看起來是打亂的。換位密碼則完全不動任何字元,只重新排列順序。
這項差異正是為何柵欄密碼解碼器在結構上比 Caesar 位移解碼器更為簡單的原因。沒有字母對字母的對映需要還原,只有一個位置還原的問題需要解決。解碼器必須找出每個密文字元來自哪一欄,將密文切割成各欄的桶,再重新組合出原始的位置順序。因為密文的字母表與明文的字母表完全相同,對 Rail Fence 輸出所做的頻率分析看起來會與對輸入所做的頻率分析一模一樣,這也是為何小的欄杆數可以在毫秒之間被暴力破解的原因。
之字形公式:欄杆如何編號
以柵欄形式書寫,意即將第一個字元放在第 0 欄,下一個放在第 1 欄,依此類推直到第 r-1 欄,接著反轉方向:第 r-2 欄、第 r-3 欄,一路回到第 0 欄,然後再向下,直到訊息用盡為止。這個之字形曲折背後的數學可以寫成一個公式。對於訊息索引 i 與欄杆數 r,計算 p = i mod 2(r-1)。若 p 小於 r,該字元屬於第 p 欄;否則它屬於第 2(r-1) - p 欄。因此,之字形的週期(也就是列模式再次重複前有多少個位置)為 2(r-1)。
該公式會產生如下所示的標準列模式。
| 欄杆數 (r) | 週期長度 2(r-1) | 重複的列模式 |
|---|---|---|
| 2 | 2 | 0, 1, 0, 1, … |
| 3 | 4 | 0, 1, 2, 1, 0, 1, 2, 1, … |
| 4 | 6 | 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, … |
| 5 | 8 | 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, … |
一旦這些列被填滿,編碼器便會由左至右串接第 0 欄,接著第 1 欄,再來第 2 欄,一路到第 r-1 欄。逐列讀取正是產生密文中可見「柵欄」的原因,而這也正是解碼器必須還原的操作。
Rail Fence 密碼解碼器如何重建原始順序
解碼是編碼的反向過程,分為三個明確階段:計算、切片、然後消耗。解碼器首先在密文長度上重建相同的列模式,並統計每欄各有多少個位置。以一段 25 字元、3 欄的訊息為例,統計結果為第 0 欄 = 7、第 1 欄 = 12、第 2 欄 = 6,合計為 25,與輸入長度完全吻合。
接著,解碼器依這些大小將密文切成若干桶。以使用 3 欄加密的標準訊息 WEAREDISCOVEREDFLEEATONCE 為例:其密文為 WECRLTEERDSOEEFEAOCAIVDEN。前 7 個字元 WECRLTE 放入第 0 欄的桶,接下來的 12 個字元 ERDSOEEFEAOC 放入第 1 欄的桶,最後 6 個字元 AIVDEN 放入第 2 欄的桶。
最後,解碼器從位置 0 走到位置 24,依列模式從對應的欄桶中各取一個字元,還原到原本的位置。位置 0 是第 0 欄,因此從第 0 欄取出 W;位置 1 是第 1 欄,因此從第 1 欄取出 E;位置 2 是第 2 欄,因此從第 2 欄取出 A;位置 3 又是第 1 欄,因此從第 1 欄取出 R,依此類推,直到原始訊息被重新組裝完成。
因為沒有猜測任何填補,也未套用任何替換,以相同的欄杆數從明文到密文再回到明文的確定性來回操作,預期會精確重現每個碼位。從某個特定欄桶輸出的每個密文字元都會回到它原本的確切位置。若有任何字元跑到錯誤的位置,表示約定或欄杆數與編碼器不符——這種不符是確定性換位解碼器唯一會犯的錯誤。
如何使用 Rail Fence 密碼解碼器
- 開啟 Rail Fence 密碼解碼器,選擇「加密」或「解密」。
- 輸入介於 2 到 100 之間的整數欄杆數。任何超出此範圍的值會以獨立的驗證失敗回報,而不是靜默地被強制改為預設值。
- 將必須參與處理的完整文字(包括每個空格、標點符號、換行或表情符號)準確貼上輸入欄位。
- 執行工具,於輸出區塊讀取結果,該區塊會保留每個碼位的可見格式。
- 複製結果時不要修剪空白,若要確認來回操作的一致性,反向操作時請使用相同的欄杆數與相同的起始欄、無偏移約定。
輸入上限為 200,000 個碼位,以確保瀏覽器中的列建構與重建能保持順暢;此外,工具是以 Unicode 碼位而非 UTF-16 碼元進行迭代,因此像 🙂 這類表情符號會被視為單一位置,絕不會被切分成兩個代理項的一半。空白的輸入與無效的欄杆數會以獨立的失敗呈現,而不是被靜默替換為猜測的預設值。
容易導致解碼器比較結果不一致的約定
即使是兩個同樣「支援三欄」的 Rail Fence 實作,也可能從同一段明文產生不同的密文,因為這個家族有多種歷史悠久的約定。本文所介紹的 Rail Fence 密碼解碼器採用一組特定的組合:從最上方欄杆開始、先向下移動、不套用任何起始偏移,並保留每個碼位,包括空格、標點與表情符號。從最下方欄杆開始、反轉方向、加上偏移,或在排列字元前先去除非字母字元的變體,即便使用相同的欄杆數,也會產生不同的結果。這正是教科書答案與網站輸出不一致的最常見原因。
作為比較,dCode Rail Fence 頁面以自身的偏移與方向控制項記錄了相同的之字形家族,而 CrypTool 的教學用柵欄模組則以類似的約定展示了經典的三欄範例。當不同工具的結果出現歧異時,首先該驗證的是約定(起始欄、偏移、方向與碼位處理方式),而不僅僅是欄杆數。希望以逐步方式偵測並調和這些不一致之處的讀者,可以參考我們的指南:如何解讀 Rail Fence 密碼:對齊約定。
為何 Rail Fence 解碼並非真正的加密
解碼 Rail Fence 密文既快速、又可逆,而且即使沒有欄杆數也極易攻擊,因為對於任何一般人寫的訊息長度來說,可行的欄杆數值寥寥無幾,且底層明文的字元頻率會被完整保留下來。防禦者只需從 2 開始逐一嘗試每個欄杆數,並對結果進行可讀性評分;在實務上,這種暴力破解在毫秒之間即可完成。這使得 Rail Fence 成為一種教學用的密碼與謎題,而非保密機制。
凡是必須真正保持機密的內容——密碼、API token、個人資料、檔案——請使用 AES-GCM 或其他經過審查的認證加密機制,而非歷史悠久的換位方式。透過 Rail Fence 密碼解碼器成功完成一次來回操作,只能證明約定與編碼器相符,絕對無法證明訊息確實被保密,因為除了欄杆數本身之外並無秘密可言,而欄杆數只能被暴力破解,無法受到保護。
相關閱讀:ROT13 解碼器範例:哪些會改變、哪些維持不變。