編碼鏈解碼器

被不止一種編碼器處理過的文本才是常態,而不是特例:Base64 令牌裡嵌著 JSON 正文、日誌行裡嵌著 URL、表單值先被百分號編碼又被 Base64 編碼以便放進請求頭。本頁一層一層解開這些編碼,標出每一步用到的技術、列印它的置信度和理由,並列出它在每一步否決了哪些技術,讓你可以不同意它的判斷。當文本不再像被編碼過、達到步數上限、或下一步會帶回已經見過的文本時停止。沒有任何靜默猜測:字母表與普通單詞重疊的技術永遠不會被自動應用,只會被列出。
所有處理都在瀏覽器本地進行——你的資料絕不上傳到任何伺服器。

初次接觸?用平實的語言解釋編碼鏈——什麼是層、為什麼編碼不是加密、以及為什麼步驟的順序很重要。
只有置信度不低於以下值時才自動應用一層:
最多解開
一次性執行上面的層數上限。兩種方式生成的是同一張表,所以你可以在任何時刻切換為手動步進。
或者手動挑選一項技術:
這個列表是頁面此刻在文本中能看到的東西。旋轉密碼始終在列表裡,因為它們根本無法被檢測;還有那些只有去掉換行排版才變得可識別的條目——它們會被明確標註,且永遠不會被自動應用。
這段輸入的長度超出了本頁不詢問就執行的範圍,上面的估計顯示可能需要 。再點一次解開整條鏈表示繼續,或者先縮短文本。
(先輸入或貼上一些內容)
(鏈將顯示在這裡)
什麼是編碼鏈,為什麼它需要專門的解碼器?

一個層就是套在文本上的一種編碼。鏈是兩層或更多層依次疊加。幾乎每個日常案例都是這樣產生的:有人需要把一段二進位制——一張圖片、一個簽名令牌——放進只能承載文本的地方,於是做了 Base64。Base64 的結果要放進 URL,於是又被百分號編碼。整個 URL 又要寫進日誌行或配置檔案,於是反斜槓或引號也被轉義。你遇到問題時看到的只是最外層,它之所以不可讀,原因很簡單:裡面的層還沒解開。

單一用途的解碼器對此無能為力。把 JTI2bHQlM0JiJTI2Z3QlM0JoaSUyNmx0JTNCJTJGYiUyNmd0JTNC 交給 Base64 解碼器,會得到一個完全正確但依然不可讀的答案,因為百分號轉義和字元引用還壓在你想要的文本之上。你真正需要的是在每一步決定該解開哪種編碼器的東西——本頁就是把這道決策過程展示出來。

編碼不是加密,本頁不破解任何東西。本頁上的每種技術都是把同樣的資訊寫下來的公開、可逆的方式。Base64 沒有金鑰。百分號轉義沒有金鑰。如果最內層是加密的,本頁會解開外層並交給你密文,並且會明說出來,而不是假裝那是結果。這裡沒有任何可執行的東西,也沒有任何可隱藏的東西。
本頁的例項演示

下面每一行都是本頁資料檔案裡的真實輸入,中間一列是本頁自己的解開器在其中的發現。最後一列是它停下來時剩下的文本。

輸入是什麼 發現的層 輸入(原樣引用) 停止時剩下

這些行由本頁根據自己的案例列表渲染,並在每次訪問時重新執行,因此它們不可能偏離程式碼的實際行為。下面的自測會逐條檢查。

本頁如何決定解開哪一層
  1. 看形狀,不看含義。每種技術都有一個簽名——一個百分號轉義、一段等長的十六進位制、一個匹配 Base64 的字母表和長度。本頁列出簽名匹配文本的每一種技術,並給出 0 到 1 之間的置信度。
  2. 先解碼,再看結果是不是文本。只有能產生可讀結果的技術才值得應用。每個候選都會真的執行一遍,其輸出按可列印字元的佔比打分。
  3. 只應用過線的,按置信度排序。置信度最高且高於你閾值的候選會被應用,然後在結果上重複這一過程。低於閾值的只列出、不應用。
  4. 本頁在此基礎上增加的一條規則。即使某項技術過了閾值,本頁也不會自動應用它,除非結果確實是可讀文本——替換字元和控制字元會被扣分。沒有這條規則,普通單詞 cafe 會被“合法地”解碼成三個只在 Latin-1 下可列印的位元組,getUserName 會被解碼成八個位元組的噪音。檢測器沒算錯——那些字串確實符合字母表;但本頁認為符合字母表並不夠。你仍然可以手動應用它們,候選列表會告訴你它拒絕的原因。
  5. 有節制地停止。當沒有技術過線、文本不再變化、達到步數上限、或下一步會帶回鏈中已經出現過的文本時停止。最後一條很重要:ROT13 是自己的逆變換,允許重複該步驟的鏈永遠不會結束。
  6. 換行排版只提供,不自動應用。如果文本被切成多行,檢測器看到的是空白,讀到的是普通散文,什麼都找不到。於是本頁把一份文本副本中的空白去掉,再次詢問檢測器,並把找到的東西作為手動選擇的步驟列出。從文本中去除空白是對文本的改寫,而本頁不會改寫任何你沒有要求改寫的東西。
本頁不會做的事
它只解碼,別的什麼都不做。你貼上的文本從不被執行:沒有 eval、沒有 new Function、沒有指令碼注入、不開啟文件。它也從不被髮送到任何地方:沒有上傳、沒有請求、沒有統計。除了頁面底部的廣告位和分享按鈕行(那是本頁載入的僅有的兩個第三方元件),不從其他主機獲取任何字型或指令碼。解碼輸出以文本形式寫入頁面,因此某一層解出來的 HTML 標籤會被顯示為文字,而不是變成真的標籤。你可以驗證這一切:按自測,它會檢查本頁自己的原始碼中是否含有這些構造,發現即失敗。
它能識別什麼,不能識別什麼
技術 單獨使用時的把握 陷阱

本頁引用的文本是為本站編寫的。Base64、Base32、Base58、Base91 和 quoted-printable 的字母表以及 uuencode 的塊格式都是公開發布的定義;解碼遵循這些定義而不是任何特定工具的怪癖。各字母表的參考向量在姊妹頁面上,那裡帶有 RFC 4648 測試向量。

以多行排版到達的文本

經過電子郵件、PEM 檔案、請求頭裡的令牌或從終端粘貼出的雜湊的資料塊通常是折行的:編碼器在固定列寬處斷行——76 個字元是 MIME 慣例——並在列末放一個換行。這些換行不是資料的一部分。它們的存在是為了讓長行能在傳輸中存活,每個讀取這種資料塊的解碼器都被期望忽略它們。

本頁不會自動忽略它們,理由就是它在其他地方使用的同一條規則。空白是“一串字元是散文而不是資料”的最強訊號,正是這個測試讓 The quick brown fox jumps over the lazy dog. 不會被讀成任何東西。折行的資料塊在那個測試看來與散文一模一樣,所以本頁在它裡面什麼也找不到——然後做誠實的那一半工作:算出如果去掉空白它會發現什麼,把手動選擇器中標為先去空白的條目列出來,然後停在那裡。之所以只列出而不應用,是因為去除空白會改動你的文本,而本頁只在能證明改動內容時才改動文本。這裡它能證明改動是什麼,卻仍然拒絕替你做,因為值中間有換行的文本和兩個欄位之間有換行的文本,從內部看起來一模一樣。

頁面在折行文本上停下時的兩步操作。切換到手動一步步進行,按一次應用下一層(這讓頁面有一條可以追加的鏈,它什麼也不改變),然後選中標記為先去空白的條目並按應用。隨之產生的那一行會說明去掉了多少個空白字元,並把它的輸入大小記為你貼上的文本,因此該行兩個數字之差正好是去掉的空白量。

同樣的推理也覆蓋方向相反的情況。uuencode 塊帶有 begin 行和每行的長度字元,因此它本身就可識別並會被自動應用;quoted-printable 正文保留自己的軟換行,由它自己的解碼器解碼,該解碼器知道行尾單個的 = 是續行而不是資料。當形狀測試無法區分散文與資料時,本頁選擇拒絕並向你展示備選項,而不是替你做決定。

本頁會執行什麼,拒絕執行什麼

下表由本頁強制執行的同一組常量構建,因此本頁的表格與警告不可能互相矛盾。讓人意外的兩行是 Base58 和 Base62:這兩種技術用長除法轉換,其開銷隨長度的平方增長,所以本頁只對短字串執行它們,並在步驟裡說明,而不是假裝卡死。

這些估計是刻意悲觀的。它們來自計時基準而不是你的機器,桌面瀏覽器通常比所示數字快好幾倍。