Unicode 详解 - 字符编码入门指南
"乱码"的困扰你一定经历过。其原因大多与字符数与字节数的区别有关。本文将解析现代文本处理不可或缺的 Unicode 基础知识。
什么是字符编码
计算机将文字作为数值处理。规定哪个数值对应哪个文字的规则就是"字符编码"。
| 字符编码 | 特点 | 主要用途 |
|---|---|---|
| ASCII | 仅英数字和符号 (128 字符) | 英语圈基础 |
| Shift_JIS | 支持日语 (约 7,000 字符) | Windows 日语环境 |
| EUC-JP | 支持日语 | Unix/Linux 日语环境 |
| Unicode (UTF-8) | 支持全球文字 (15 万字符以上) | Web 标准 |
需要注意的是,"字符编码"和"编码方式"严格来说是不同的概念。Unicode 定义了字符集合和码点分配,UTF-8 和 UTF-16 是将 Unicode 码点转换为字节序列的方式。Unicode 技术解析书籍可以帮助深入理解。
Unicode 的诞生背景
过去各国和地区使用不同的字符编码,跨环境传输文本时频繁出现乱码。Unicode 就是为解决这一问题而设计的国际标准,旨在用一个体系处理全球所有文字。Unicode 的构想始于 1987 年左右,最初计划用 16 位 (65,536 字符) 表示全球文字,但仅中日韩汉字就达数万字,最终扩展到 21 位 (约 110 万字符) 的空间。
UTF-8 与 UTF-16 的区别
| 方式 | 每字符字节数 | 特点 |
|---|---|---|
| UTF-8 | 1-4 字节 | ASCII 兼容,Web 标准 |
| UTF-16 | 2 或 4 字节 | JavaScript 内部使用 |
| UTF-32 | 固定 4 字节 | 处理简单但体积大 |
Web 上 UTF-8 是事实上的标准。据 W3Techs 调查,约 98% 的网站使用 UTF-8。
乱码的实例
- UTF-8 文件用 Shift_JIS 打开:中文变成乱码字符串。
- CSV 文件乱码:Excel 默认将 CSV 视为 Shift_JIS (Windows),UTF-8 的 CSV 需要带 BOM 保存或指定编码。
- 数据库乱码:MySQL 表的字符集为 latin1 时存入中文数据会导致数据损坏。应使用 utf8mb4 而非 utf8。
对字符计数的影响
同一字符串在不同编码下字节数不同。例如"你好"是 2 个字符,但 UTF-8 下为 6 字节。字符计数器同时显示字符数和字节数,可根据用途进行确认。
还需注意 Unicode 的"正规化"(Normalization) 问题。同一外观的字符可能由不同的码点序列表示。字符串处理编程入门书籍可以帮助深入了解。
绘文字与 Unicode
绘文字是 Unicode 中特别复杂的领域。看起来是 1 个字符,内部可能由多个码点组成。例如家庭绘文字"👨👩👧👦"由 7 个码点构成,某些程序会将其计为 7 个字符。这是通过 ZWJ (零宽连接符) 实现的。
常见误解与注意事项
- "Unicode = UTF-8"是错误的:Unicode 是字符集标准,UTF-8 是其编码方式之一。
- "1 个码点 = 1 个字符"是错误的:组合字符和 ZWJ 序列中,多个码点构成一个"视觉字符"。
- "UTF-8 总是 3 字节"是错误的:ASCII 为 1 字节,部分欧洲语言字符为 2 字节,绘文字为 4 字节。
- "String.length 能获取字符数"是危险的:JavaScript 的 .length 返回 UTF-16 代码单元数,包含代理对的字符会返回比实际字符数更大的值。
总结
Unicode 是现代文本处理的基础,理解其历史和机制可以从根本上解决乱码和字符计数问题。请使用字符计数器确认字符数和字节数。