常见编码的识别方式与判断技巧
整理常见编码的外观特征、示例、易混淆点、多层编码判断方法和常用验证工具。
在 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 |
<、" |
HTML 命名实体 | <script> |
<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 |
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,就说明可能还有下一层。
推荐按下面的顺序判断:
- 保留原始数据,避免在反复尝试中丢失内容。
- 观察字符范围、长度、分隔符、前缀和结尾。
- 结合上下文判断数据来自 URL、Cookie、JWT、邮件还是程序源码。
- 每次只解一层,并记录使用了什么方式。
- 解码后检查是否出现可读文本、JSON、文件头或新的编码特征。
- 如果解码结果乱码,不要立即认定方法错误,还要考虑字符集、压缩数据或二进制文件。
常见嵌套特征:
%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 等字符集,也要考虑结果是否为压缩包、图片等二进制内容。
- 记录每一层的处理顺序。多层编码题最容易因为顺序混乱而无法复现。