HEX(十六进制)表示法把每个字节写成两个十六进制字符(00~FF)。文本、图片、协议帧在计算机底层都是字节——会读 HEX,就能在”出了什么问题”和”字节层面发生了什么”之间直接对话。
为什么需要 HEX
文本编辑器隐藏了字节细节:你看到”你好”,编辑器把 UTF-8 字节渲染成汉字。但有些问题只在字节层面可见:
- 文件头的魔数(判断真实格式)
- BOM 字节(解释跨平台乱码)
- 换行符类型(CRLF vs LF)
- 协议帧的固定字段(调试自定义协议)
- 空字节(
00)或不可见控制字符
这些问题靠文本编辑器看不到,靠 HEX 一眼清楚。
字节和 HEX 的关系
1 字节 = 8 位 = 0~255 的整数 = 2 个十六进制字符。
十进制 十六进制 二进制
0 00 00000000
16 10 00010000
255 FF 11111111
一段文本转成 HEX:
文本:Hello
ASCII:H=72 e=101 l=108 l=108 o=111
HEX: 48 65 6C 6C 6F
“Hello” → 48 65 6C 6C 6F(5 字节 = 10 个 hex 字符)
UTF-8 的变长编码
UTF-8 用 1 到 4 字节表示一个 Unicode 字符:
| 字符范围 | 字节数 | hex 字节模式 | 示例 |
|---|---|---|---|
| ASCII(U+0000~U+007F) | 1 | 0xxxxxxx | A = 41 |
| U+0080~U+07FF | 2 | 110xxxxx 10xxxxxx | é = C3 A9 |
| U+0800~U+FFFF(大多数汉字) | 3 | 1110xxxx 10xxxxxx 10xxxxxx | 汉 = E6 B1 89 |
| U+10000~U+10FFFF(Emoji 等) | 4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 😀 = F0 9F 98 80 |
关键观察:UTF-8 字节以 1110 开头 → 这是一个三字节字符的起始,后两个字节以 10 开头是延续字节。这种设计让 UTF-8 自同步——从任意字节开始都能判断是起始还是延续。
乱码判断:如果你看到形如 C3 A9 的字节被解析成了两个 Latin-1 字符(é),就是 UTF-8 被当 Latin-1 读了。反过来,GBK 的汉字字节(双字节)被当 UTF-8 读,延续字节模式对不上会出现替换字符 �。
文件魔数速查
文件的”真实身份”藏在前几字节,与扩展名无关:
| 格式 | 魔数(hex) | ASCII 可读部分 |
|---|---|---|
| JPEG | FF D8 FF | — |
| PNG | 89 50 4E 47 0D 0A 1A 0A | ‰PNG\r\n |
| GIF | 47 49 46 38 | GIF8 |
25 50 44 46 | %PDF | |
| ZIP | 50 4B 03 04 | PK |
| 7z | 37 7A BC AF 27 1C | 7z |
| ELF | 7F 45 4C 46 | \x7fELF |
| class(Java) | CA FE BA BE | — |
| UTF-8 BOM | EF BB BF + 内容 | — |
| UTF-16 LE | FF FE + 内容 | — |
用法:把文件前 16 字节粘进工具,对照上表,就能判断文件真实格式——对鉴定”被改扩展名的文件”或”服务器返回 Content-Type 不可信时”很有用。
协议调试场景
自定义二进制协议帧
假设协议格式是:
[2字节 magic] [1字节 version] [4字节 body长度] [body]
收到的 hex 是:
AB CD 01 00 00 00 05 68 65 6C 6C 6F
逐段解析:
AB CD→ magic header ✅01→ version 100 00 00 05→ body 长度 = 5(大端序)68 65 6C 6C 6F→ body = “hello”(ASCII)
检查换行符类型
一个”在 Windows 上正常、Linux 上多出 \r”的脚本:
hex 末尾:... 73 63 72 69 70 74 0D 0A
^^^^
CRLF,多了一个 0D
用工具把内容粘进去,看每行末尾是 0A(LF)还是 0D 0A(CRLF)。
检查数字签名 / HMAC 的字节
调试签名对不上时,两端各把签名 hex dump 出来,逐字节对比。大小写混用(abCD vs ABCD)不影响,但多一个空格或换行会让整个签名不一样。
工具使用技巧
- 文本 → HEX:输入任意文本,选编码(UTF-8 / GBK / Latin-1),输出十六进制字节流
- HEX → 文本:粘入字节序列(带不带空格均可),选解码编码,还原原始文本
- 分隔符:可以选输出格式——带空格(
E6 B1 89)、不带(E6B189)、\x前缀(\xE6\xB1\x89)——对应不同语言的字节字面量风格