字符编码
定义字符与比特序列对应关系的规则体系。由字符集 (定义包含哪些字符) 和编码方案 (定义如何转换为字节序列) 两个层次构成。
字符编码 (character encoding) 是计算机处理文字的基础技术。它规定了如何将人类可读的「A」或「中」转换为计算机能处理的数值。没有这套转换规则,文本的存储、传输和显示都无从谈起。
字符编码分为两个层次来理解最为清晰。第一层是「字符集」(character set),定义了系统能处理哪些字符。ASCII 包含 128 个字符,GB2312 包含 6,763 个汉字,Unicode 则涵盖超过 15 万个字符。第二层是「编码方案」(encoding scheme),定义了字符集中的每个字符用什么样的字节序列来表示。同一个 Unicode 字符集对应着 UTF-8、UTF-16、UTF-32 等不同的编码方案,原因就在于此。
中文字符编码有着复杂的历史。1980 年中国发布了 GB2312 标准,收录 6,763 个汉字。随后 GBK (1995 年) 将字符数扩展到 21,886 个,GB18030 (2000 年) 则进一步扩展并成为国家强制标准。与此同时,台湾和香港使用 Big5 编码。日本方面,基于 JIS X 0208 字符集衍生出 Shift_JIS、EUC-JP、ISO-2022-JP 三种编码方案。多种编码并存的局面,正是乱码问题频发的根源。
目前,Unicode + UTF-8 的统一趋势已不可逆转。UTF-8 与 ASCII 完全向后兼容,英文字符占 1 字节,中文汉字占 3 字节。这种可变长设计既保持了与 ASCII 系统的兼容性,又能表示世界上所有的文字。Web、数据库、编程语言的默认编码均已采用 UTF-8,新项目几乎没有理由选择其他编码。
在字符计数中,理解字符编码至关重要。同一个「中」字,在 UTF-8 中占 3 字节,在 GBK 中占 2 字节,在 UTF-32 中占 4 字节。「字符数」与「字节数」只有在 ASCII 范围内才一致,中文文本中两者始终不同。数据库的 VARCHAR(255) 究竟是「255 个字符」还是「255 个字节」,取决于字符编码的设置,不搞清楚就可能导致数据被截断。
实务中需要注意的是,与遗留系统对接时仍可能需要转换为 GBK 或 Big5。此时,Unicode 中存在而 GBK 中没有的字符 (如部分 emoji、CJK 统一汉字扩展 B 以后的汉字) 将无法转换,会被替换为「?」或「〓」。字符编码转换是一种可能伴随信息丢失的不可逆操作,这一点必须牢记。