认识一下Unicode(统一码)

一、Unicode是什么

Unicode(统一码/万国码)是一套字符编码标准,目标是为世界上所有语言的每一个字符分配一个唯一的数字编号,从而解决不同编码系统之间互不兼容的问题;

为什么要给每个字符分配一个唯一数字编号呢

计算机本质上只处理数字,而人类使用的是文字、符号和表情。Unicode 的作用就是建立一套"人类字符 ↔ 计算机数字"的统一对应关系。

在Unicode出现之前,各国都有自己的编码方式,比如:

编码 各国字符
ASCII 英文字符
GBK 中文字符
Shift_JIS 日文

不同编码之间不兼容,同一个数字,在不同的编码中,表示的含义并不相同,就可能导致乱码问题频发,Unicode试图"一统天下"

二、核心概念

1. Character(字符)

人看到的:

复制代码
😀

叫字符。

2. Code Point(码点)

Unicode 编号:

复制代码
U+1F600

目前 Unicode 的码点范围是 U+0000U+10FFFF,理论上能容纳超过 100 万个字符。

3. Encoding(编码)

转换:

复制代码
U+1F600
        |
        ↓
UTF-8

F0 9F 98 80

4. Code Unit(编码单元)

某种编码的基本单位。

例如:

UTF-8,UTF-8 最聪明的地方在于它的可变长度设计(占用 1 到 4 个字节)

复制代码
英文字符/数字:只占 1 个字节(8 位)。

欧洲文字:通常占 2 个字节。

中/日/韩文:通常占 3 个字节。

罕见字与 Emoji:占 4 个字节。

UTF-8既然是可变长的,那系统是怎么知道一个字符占用了哪几个字节,在什么地方结束的呢?

答:系统之所以能准确识别"这个字符从哪里开始、占用几个字节、到哪里结束",关键在于 UTF-8 设计了一套非常巧妙的前缀自标记规则。

简单来说,字节开头的"前几位(bit)"就是指示灯,告诉系统当前字节是单字节字符、多字节字符的开头,还是随后的接应字节。


Unicode 本身只是一张"字符→编号"的映射表 ,它不规定这些编号在计算机里如何用字节存储。

真正决定"如何存成字节"的,是具体的编码方式,常见的有 UTF-8、UTF-16、UTF-32。

三、常见编码方式对比

编码 每个字符占用字节数 特点
UTF-8 1~4 字节(可变长) 兼容 ASCII,英文占1字节,中文通常占3字节;互联网、大多数系统的主流选择
UTF-16 常用字符占2字节,辅助平面字符占 4字节 Windows、Java、JavaScript 内部常用
UTF-32 固定4字节 简单但浪费空间,较少使用

四、为什么会有乱码?

乱码本质上是编码和解码方式不一致导致的。比如:

  • 一个文件用 UTF-8 编码保存
  • 但打开时用 GBK 方式去解码

这样字节序列被错误地"翻译"成了别的字符,就出现了乱码(如常见的"锟斤拷"现象)。

五、几个常见误解总结

❌ Unicode 是一种编码

不准确。

正确:

Unicode 是字符集合和编号标准。


❌ UTF-8 可以表示的字符比 Unicode 多

错误。

正确:

UTF-8 是 Unicode 的一种编码实现。


❌ 一个字符一定占两个字节

错误。

例如 UTF-8:

复制代码
A
1字节

中
3字节

😀
4字节

六、GBK与UTF-8的关系

简单来说,GBK 和 UTF-8 是两种不同的字符编码方式 。它们最核心的区别在于:GBK 是中国国家标准局制定的区域性编码,专门用来解决中文显示;而 UTF-8 是国际通用的 Unicode 编码实现方式,旨在统全世界所有的语言。

它们之间既有各自的适用场景,也经常在日常使用中因为"互不兼容"而导致乱码。


核心区别对比

维度 GBK 编码 UTF-8 编码
支持语言 主要支持中文(简体/繁体)、英文字符 全球所有语言(汉字、韩文、日文、阿拉伯文、Emoji 等)
字符集基础 基于中国国家标准 GB2312 扩展 基于国际 Unicode 标准
存储长度 英文字符 1 字节,中文字符 2 字节 英文字符 1 字节,常用中文字符 3 字节
兼容性 仅在国内或老旧 Windows 系统广泛使用 全球互联网标准,跨平台、跨语言兼容性极佳
应用场景 旧版 Windows 软件、部分国内老旧数据库 网页开发、Linux 操作系统、现代 API、软件接口

它们之间的关键关系

1. 兼容 ASCII,但互相不兼容

  • 兼容 ASCII :无论在 GBK 还是 UTF-8 中,基础的英文和数字(如字母 A、数字 1)都只占 1 个字节,且两者二进制值完全一致。
  • 中文互相不不兼容 :同一个汉字(比如"中"),在 GBK 中占用 2 个字节 ,而在 UTF-8 中占用 3 个字节 。由于它们的二进制映射映射表完全不重合,因此如果用 GBK 方式打开 UTF-8 保存的中文文本,就会产生乱码(常见的比如"锟斤拷"或各种奇怪符号)。

2. Unicode 是它们转换的"桥梁"

GBK 和 UTF-8 不能直接进行简单的数学转换 。如果你要把一个 GBK 编码的文件转成 UTF-8,必须借助 Unicode(万国码):

GBK 字节→查找 GBK 映射表Unicode 码点→应用 UTF-8 编码规则UTF-8 字节\text{GBK 字节} \xrightarrow{\text{查找 GBK 映射表}} \text{Unicode 码点} \xrightarrow{\text{应用 UTF-8 编码规则}} \text{UTF-8 字节}GBK 字节查找 GBK 映射表 Unicode 码点应用 UTF-8 编码规则 UTF-8 字节

也就是说,Unicode 相当于"世界语",任何本土编码(GBK、Big5、Shift-JIS 等)都需要先翻译成 Unicode,才能转写为 UTF-8。


为什么存储中文时长度不同?

  • GBK 更节省空间(针对纯中文) :因为 GBK 只需要服务中文和英文,采用双字节定长编码中文,因此一个包含 1000 个汉字的文件在 GBK 下大约占用 2 KB
  • UTF-8 扩展性更好(但中文略变大) :为了兼容全世界数十万种字符,UTF-8 对汉字采用了 3 字节(部分偏僻字 4 字节)的变长编码。同样 1000 个汉字在 UTF-8 下大约占用 3 KB

提示 :虽然 UTF-8 存中文比 GBK 多消耗 50% 的空间,但现代硬件对这几 KB 的体积并不敏感,跨平台无乱码的通用性远比节省这一点空间重要得多。


实际开发与使用建议

  1. 新建项目一律优先选择 UTF-8:不论是写代码、建数据库、做网页还是保存 txt 文件,统一使用 UTF-8 可以规避 99% 的乱码问题。
  2. 遇到乱码怎么排查 :当你在 Windows 控制台或 Python 读写文件发现中文变乱码时,通常是因为源文件的保存格式当前软件/终端的默认读取格式不一致(例如文件是 UTF-8,但终端以 GBK 打开)。

Unicode 是给世界所有字符分配唯一编号的标准;UTF-8、UTF-16、UTF-32 是把这些编号转换成计算机字节的不同方法。程序内部通常处理 Unicode,存储和通信时选择某种 UTF 编码。

相关推荐
GeekZHR29 分钟前
C语言指针进阶补充6:动态内存管理、mem系列内存函数、复杂指针声明,一次补齐指针的“三大盲区“
java·c语言·算法·指针
侧耳倾听11136 分钟前
java 日志框架简介
java·开发语言
IT古董1 小时前
【WMS学习笔记系列】01-需求分析
大数据·数据库
zlinear数据采集卡1 小时前
数据采集卡从入门到精通(9):分辨率与精度——16位卡不等于1/65536的精度
开发语言·数据库·fpga开发·开源·c#
她的男孩1 小时前
我用 LLM 把后台 CRUD 效率提升 10 倍:AI 代码生成器的架构与落地实践
java·后端·架构
Mico181 小时前
麒麟v10-MySQL InnoDB Cluster 完整部署与全场景验证(从入门到精通)
数据库·mysql
土司大王2 小时前
LeetCode hot100——移动零
java·算法·leetcode
杨云龙UP2 小时前
生产环境MySQL多实例XtraBackup全量备份与rsync异地自动传输实践
linux·运维·数据库·mysql·xtrabackup·主从复制·备份恢复
thefool1122662 小时前
相同的树`
java