编码链解码器
被不止一种编码器处理过的文本才是常态,而不是特例:Base64 令牌里嵌着 JSON 正文、日志行里嵌着 URL、表单值先被百分号编码又被 Base64 编码以便放进请求头。本页一层一层解开这些编码,标出每一步用到的技术、打印它的置信度和理由,并列出它在每一步
否决 了哪些技术,让你可以不同意它的判断。当文本不再像被编码过、达到步数上限、或下一步会带回已经见过的文本时停止。没有任何静默猜测:字母表与普通单词重叠的技术永远不会被自动应用,只会被列出。
所有处理都在浏览器本地进行——你的数据绝不上传到任何服务器。
初次接触? 用平实的语言解释编码链 ——什么是层、为什么编码不是加密、以及为什么步骤的顺序很重要。
自动逐层解开
手动一步步进行
只有置信度不低于以下值时才自动应用一层:
0.85 — 谨慎(只含有明确签名的技术)
0.70 — 正常(推荐)
0.20 — 激进(加入 Base58、Base62 和 basE91,它们与普通单词重叠)
最多解开
1 层
2 层
3 层
4 层
5 层
6 层
7 层
8 层
载入一个示例链
自测
解开整条链
再解一层
重新开始
一次性执行上面的层数上限。两种方式生成的是同一张表,所以你可以在任何时刻切换为手动步进。
应用下一层
撤销上一层
重新开始
或者手动挑选一项技术:
应用
这个列表是页面此刻在文本中能看到的东西。旋转密码始终在列表里,因为它们根本无法被检测;还有那些只有去掉换行排版才变得可识别的条目——它们会被明确标注,且永远不会被自动应用。
这段输入的长度超出了本页不询问就运行的范围,上面的估计显示可能需要 。再点一次解开整条链 表示继续,或者先缩短文本。
(链将显示在这里)
复制取的是该层解开之后的文本。回滚会丢弃该层及其上的所有层,这也是一次撤销多步的方法。
解开 0 层后的结果
(还没有内容)
复制结果
把结果作为新输入
下载报告(JSON)
什么是编码链,为什么它需要专门的解码器?
一个层 就是套在文本上的一种编码。链 是两层或更多层依次叠加。几乎每个日常案例都是这样产生的:有人需要把一段二进制——一张图片、一个签名令牌——放进只能承载文本的地方,于是做了 Base64。Base64 的结果要放进 URL,于是又被百分号编码。整个 URL 又要写进日志行或配置文件,于是反斜杠或引号也被转义。你遇到问题时看到的只是最外层,它之所以不可读,原因很简单:里面的层还没解开。
单一用途的解码器对此无能为力。把 JTI2bHQlM0JiJTI2Z3QlM0JoaSUyNmx0JTNCJTJGYiUyNmd0JTNC 交给 Base64 解码器,会得到一个完全正确但依然不可读的答案,因为百分号转义和字符引用还压在你想要的文本之上。你真正需要的是在每一步决定该解开哪种 编码器的东西——本页就是把这道决策过程展示出来。
编码不是加密,本页不破解任何东西。 本页上的每种技术都是把同样的信息写下来的公开、可逆的方式。Base64 没有密钥。百分号转义没有密钥。如果最内层是加密的,本页会解开外层并交给你密文,并且会明说出来,而不是假装那是结果。这里没有任何可运行的东西,也没有任何可隐藏的东西。
本页的实例演示
下面每一行都是本页数据文件里的真实输入,中间一列是本页自己的解开器在其中的发现。最后一列是它停下来时剩下的文本。
这些行由本页根据自己的案例列表渲染,并在每次访问时重新运行,因此它们不可能偏离代码的实际行为。下面的自测会逐条检查。
本页如何决定解开哪一层
看形状,不看含义。 每种技术都有一个签名——一个百分号转义、一段等长的十六进制、一个匹配 Base64 的字母表和长度。本页列出签名匹配文本的每一种技术,并给出 0 到 1 之间的置信度。
先解码,再看结果是不是文本。 只有能产生可读结果的技术才值得应用。每个候选都会真的运行一遍,其输出按可打印字符的占比打分。
只应用过线的,按置信度排序。 置信度最高且高于你阈值的候选会被应用,然后在结果上重复这一过程。低于阈值的只列出、不应用。
本页在此基础上增加的一条规则。 即使某项技术过了阈值,本页也不会自动应用它,除非结果确实是可读文本——替换字符和控制字符会被扣分。没有这条规则,普通单词 cafe 会被“合法地”解码成三个只在 Latin-1 下可打印的字节,getUserName 会被解码成八个字节的噪音。检测器没算错——那些字符串确实符合字母表;但本页认为符合字母表并不够。你仍然可以手动应用它们,候选列表会告诉你它拒绝的原因。
有节制地停止。 当没有技术过线、文本不再变化、达到步数上限、或下一步会带回链中已经出现过的文本时停止。最后一条很重要:ROT13 是自己的逆变换,允许重复该步骤的链永远不会结束。
换行排版只提供,不自动应用。 如果文本被切成多行,检测器看到的是空白,读到的是普通散文,什么都找不到。于是本页把一份文本副本中的空白去掉,再次询问检测器,并把找到的东西作为手动选择的步骤列出。从文本中去除空白是对文本的改写,而本页不会改写任何你没有要求改写的东西。
本页不会做的事
它只解码,别的什么都不做。 你粘贴的文本从不被执行:没有 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:这两种技术用长除法转换,其开销随长度的平方增长,所以本页只对短字符串运行它们,并在步骤里说明,而不是假装卡死。
这些估计是刻意悲观的。它们来自计时基准而不是你的机器,桌面浏览器通常比所示数字快好几倍。