常见编码的识别方式与判断技巧

整理常见编码的外观特征、示例、易混淆点、多层编码判断方法和常用验证工具。

  • #编码
  • #CTF
  • #Web安全
  • #CyberChef

在 CTF、Web 安全测试和日常排查中,可以先根据字符范围、分隔符、固定前缀和长度,大致判断一段数据可能使用了什么编码。

但这些特征只能用于缩小范围,不能仅凭外观直接下结论。最稳妥的方法仍然是结合数据出现的位置,尝试解码后检查结果是否合理。

一、常见特征速查

看到的特征 优先想到 示例 解码结果或说明
%2F%3D%20 URL 编码 %61%64%6D%69%6E admin
%252F 双重 URL 编码 %252F 第一次得到 %2F,第二次得到 /
YWRtaW4= Base64 YWRtaW4= admin
只含字母、数字、-、_ Base64URL eyJ1c2VyIjoiYWRtaW4ifQ 常用于 JWT,结尾通常省略 =
三段内容以 . 分隔 JWT xxxxx.yyyyy.zzzzz Header、Payload、Signature
61646d696e 十六进制(Hex) 61646d696e admin
\x61\x64 十六进制转义 \x61\x64\x6d\x69\x6e admin
\u0061\u0064 Unicode 转义 \u0061\u0064\u006d\u0069\u006e admin
<、< HTML 数字实体 admin admin
&lt;、&quot; HTML 命名实体 &lt;script&gt; <script>
01100001 二进制 01100001 01100100 01101101 01101001 01101110 admin
97 100 109 ASCII 十进制 97 100 109 105 110 admin
\141\144 八进制转义 \141\144\155\151\156 admin
大写字母和数字 2-7 Base32 JBSWY3DP Hello
不出现 0、O、I、l 可能是 Base58 JxF12TrwUP45BMd 常见于区块链地址和短数据编码
大量 =XX Quoted-Printable admin=40example.com admin@example.com
s:5:"admin"; PHP 序列化 s:5:"admin"; 长度为 5 的字符串 admin
32 位十六进制 可能是 MD5 5f4dcc3b5aa765d61d8327deb882cf99 长度只是线索,不能单独确认
40 位十六进制 可能是 SHA-1 — 也可能只是普通十六进制数据
64 位十六进制 可能是 SHA-256 — 也可能是密钥、随机数或其他数据

速记:%XX 看 URL,= 结尾看 Base64,纯 0-9a-f 看 Hex 或哈希,\u 看 Unicode,&# 看 HTML 实体,三个点分段看 JWT。

二、几个容易混淆的地方

1. Base64 和 Base64URL

普通 Base64 常见字符为:

A-Z a-z 0-9 + / =

Base64URL 会把 +、/ 分别替换为 -、_,并且经常省略末尾的 =。JWT 的 Header 和 Payload 就使用 Base64URL。

需要注意:JWT 的 Header 和 Payload 只是编码,不是加密。拿到 JWT 后通常可以直接解码查看内容,但第三段 Signature 是签名,不能通过“解码”得到密钥。

2. 十六进制和哈希

纯十六进制字符串不一定是哈希。它也可能是:

  • 普通文本的十六进制表示
  • 文件内容或文件头
  • 随机数
  • 密钥或令牌
  • 二进制数据

可以先尝试按 Hex 解码。如果结果是可读文本、JSON 或文件头,就不应只因为长度刚好是 32、40 或 64 位而认定它是哈希。

常见文件头的十六进制特征:

文件类型 文件头
PNG 89 50 4E 47
JPEG FF D8 FF
ZIP 50 4B 03 04
PDF 25 50 44 46

3. URL 编码中的 +

在查询字符串和 application/x-www-form-urlencoded 表单中,+ 通常会被当作空格;真正的加号一般写成 %2B。

例如:

a+b     -> a b
a%2Bb   -> a+b

4. PHP 序列化中的长度

s:5:"admin";

其中 5 表示字符串的字节长度。修改字符串内容后,如果长度没有同步修改,反序列化可能失败。中文等多字节字符尤其要注意字节数不一定等于字符数。

5. Quoted-Printable 和 URL 编码

两者都可能出现十六进制形式:

  • URL 编码使用 %XX
  • Quoted-Printable 使用 =XX

Quoted-Printable 常见于电子邮件正文和邮件头,行尾单独出现的 = 还可能表示下一行是当前行的延续。

三、编码、哈希和加密的区别

编码(Encoding)

目的是改变数据的表示形式,通常不需要密钥,可以直接还原。

常见例子:Base64、URL 编码、Hex、HTML 实体。

哈希(Hash)

目的是生成固定长度的摘要,正常情况下不可逆。

常见例子:MD5、SHA-1、SHA-256。

网上所谓“MD5 解密”通常不是解密,而是在已有字典或数据库中查找相同哈希值对应的原文。

加密(Encryption)

目的是保护数据机密性,需要正确的密钥才能解密。

常见例子:AES、RSA。

因此,看到一段不可读内容时,不要把编码、哈希和加密都统称为“加密”。先判断它是否具有可逆编码的特征。

四、多层编码的判断方法

实际题目中经常会把多种编码叠加,例如:

YWRtaW4lMjBG

第一层看起来像 Base64。解码后如果仍然出现 %XX、\uXXXX、纯十六进制或另一段 Base64,就说明可能还有下一层。

推荐按下面的顺序判断:

  1. 保留原始数据,避免在反复尝试中丢失内容。
  2. 观察字符范围、长度、分隔符、前缀和结尾。
  3. 结合上下文判断数据来自 URL、Cookie、JWT、邮件还是程序源码。
  4. 每次只解一层,并记录使用了什么方式。
  5. 解码后检查是否出现可读文本、JSON、文件头或新的编码特征。
  6. 如果解码结果乱码,不要立即认定方法错误,还要考虑字符集、压缩数据或二进制文件。

常见嵌套特征:

  • %25:可能是 URL 编码后的 %,提示存在双重 URL 编码。
  • Base64 解码后出现 {:可能是 JSON。
  • Base64 解码后以 PK 开头:可能是 ZIP 文件。
  • Hex 解码后出现 89504E47 对应的文件头:可能是 PNG 图片。
  • 解码后仍只包含 Base64 字符:可能还有一层 Base64,但也可能只是巧合。

五、常用验证方式

Linux 命令

Base64 解码:

printf '%s' 'YWRtaW4=' | base64 -d

十六进制解码:

printf '%s' '61646d696e' | xxd -r -p

查看文件类型:

file decoded.bin

查看文件头:

xxd -l 32 decoded.bin

CyberChef

适合快速尝试 Base64、URL、Hex、字符集转换和多层编码。使用 Magic 功能时不要完全依赖自动判断,最好逐层确认每一步结果。

Burp Suite Decoder

适合在 Web 请求分析过程中快速进行 URL、HTML、Base64 和 Hex 的编码与解码,方便把处理后的内容继续放回请求中验证。

六、实用经验

  • 先看数据出现在哪里。URL 参数里的 %XX、JWT 中的点分段、邮件中的 =XX,上下文往往比字符串外观更可靠。
  • 不要只凭结尾的 = 判断 Base64,普通文本也可能以等号结尾。
  • Base64 解码成功不代表判断一定正确,应继续检查结果是否符合语义。
  • 哈希长度只是提示,不是证据。32 位十六进制也可能是随机 Token。
  • 对来源不明的数据进行解码时,只查看内容,不要直接执行解码出来的脚本或程序。
  • 遇到乱码时检查 UTF-8、GBK 等字符集,也要考虑结果是否为压缩包、图片等二进制内容。
  • 记录每一层的处理顺序。多层编码题最容易因为顺序混乱而无法复现。