HEX 与文本互转:字节、UTF-8 编码和开发者实用场景

· 约 3 分钟 📝 HEX ↔ 文本

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)10xxxxxxxA = 41
U+0080~U+07FF2110xxxxx 10xxxxxxé = C3 A9
U+0800~U+FFFF(大多数汉字)31110xxxx 10xxxxxx 10xxxxxx = E6 B1 89
U+10000~U+10FFFF(Emoji 等)411110xxx 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 可读部分
JPEGFF D8 FF
PNG89 50 4E 47 0D 0A 1A 0A‰PNG\r\n
GIF47 49 46 38GIF8
PDF25 50 44 46%PDF
ZIP50 4B 03 04PK
7z37 7A BC AF 27 1C7z
ELF7F 45 4C 46\x7fELF
class(Java)CA FE BA BE
UTF-8 BOMEF BB BF + 内容
UTF-16 LEFF 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 1
  • 00 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)——对应不同语言的字节字面量风格

配套工具

  • Hex 二进制查看 — 上传完整文件做 hex dump,不是粘文本
  • Hash — 计算文件的 MD5/SHA256,验证字节完整性
  • Base64 — 字节序列在文本协议(HTTP、SMTP)里的另一种传输编码
  • 字幕格式转换 — 字幕乱码根源往往是编码问题,可配合 hex 确认

❓ 常见问题

一个汉字在 HEX 里占几位?

UTF-8 编码下占 6 个十六进制字符(3 字节)。UTF-8 是变长编码——ASCII 字符(英文、数字、标点)1 字节 = 2 个 hex 字符;CJK 汉字(大部分常用汉字)3 字节 = 6 个 hex 字符;部分生僻字和 Emoji 4 字节 = 8 个 hex 字符。示例:"汉"的 UTF-8 是 E6 B1 89,"😀"是 F0 9F 98 80。所以"你好"在 UTF-8 hex 里是 12 个字符:E4 BD A0 E5 A5 BD

EF BB BF 是什么?

这是 UTF-8 BOM(Byte Order Mark),字节序标记。微软系工具(记事本、Excel 另存为 UTF-8)默认在文件开头加这 3 字节。BOM 的设计初衷是标识 UTF-16 的字节序(大端/小端),挪到 UTF-8 上本来是多余的,但 Windows 生态传了下来。问题:Linux/macOS 工具、大多数 Web 服务器、YAML/JSON 解析器都不期望 BOM——读到 EF BB BF 可能报错或显示乱码。如果你的 UTF-8 文件在 Linux 上有问题,先用 hex 看前 3 字节是不是 EF BB BF,是的话用工具去掉 BOM 重新保存。

怎么用 HEX 判断文件真实类型?

文件头的固定字节序列叫"魔数(Magic Number)",比扩展名更可靠。改扩展名不改魔数——.jpg 改成 .png 打不开,但 hex 头依然是 JPEG 的 FF D8 FF。常见文件魔数:(1) JPEG: FF D8 FF;(2) PNG: 89 50 4E 47 0D 0A 1A 0A(即 \x89PNG\r\n\x1a\n);(3) PDF: 25 50 44 46(ASCII 的 %PDF);(4) ZIP: 50 4B 03 04;(5) ELF(Linux 可执行文件): 7F 45 4C 46;(6) GIF: 47 49 46 38(ASCII 的 GIF8)。工具里把文件内容粘进去看前几个字节,就能判断真实格式。

调试 HTTP / TCP 协议时 HEX 有什么用?

协议调试里 hex 是读原始字节的标准手段。场景:(1) 自定义二进制协议——消息头通常是固定长度的字节字段(2 字节消息类型 + 4 字节 body 长度),直接看 hex 确认字节对不对;(2) 检查 Content-Type 是不是真的 UTF-8——服务器声称 UTF-8,但实际返回了 GBK,hex 里看第一个汉字字节段 < 80 还是 > 80;(3) websocket / MQTT 帧——帧头是固定位图,用 hex 手算 opcode、payload 长度;(4) Base64 decoded 之后的原始字节——用 hex 确认解码后是期望的格式。

行尾换行符在 HEX 里是什么?

换行有三种,hex 里清楚可见:(1) 0A(LF, \n)—— Unix/Linux/macOS 标准;(2) 0D 0A(CRLF, \r\n)—— Windows 标准;(3) 0D(CR)—— 古老 Mac OS 9 以前,现在几乎不用。跨平台脚本出错、Git diff 出现大量无意义变更、Python 读文件多出 \r——往往就是 CRLF 混进 LF 文件。用 hex 看行尾,0A 前有没有 0D 一目了然,不用猜。

📝 打开 HEX ↔ 文本 十六进制与文本互转·UTF-8/Latin-1/ASCII/UTF-16/GBK/GB18030 七编码·BOM 识别·乱码诊断·本地解析