Unicode 是什么?和 ASCII、UTF-8 有什么区别

Unicode 是一套字符编号标准:它给世界上每个字符分配一个唯一编号(码点),但不规定这些编号在文件或网络里怎么变成字节。ASCII 是它之前的英文专用字符集,只有 128 个字符;UTF-8、UTF-16 则是把 Unicode 码点实际存成字节的编码方式。遇到乱码时,问题几乎总是出在“编码方式”这一层,而不是 Unicode 本身。

三个概念,各管一件事

概念 管什么 范围/形式 典型例子
ASCII 字符集 128 个字符,覆盖英文、数字、标点和控制符 A = 65
Unicode 字符集(编号表) 给全球字符分配码点,如 U+4E2D 中 = U+4E2D
UTF-8 / UTF-16 编码方式 把码点转成字节序列 U+4E2D 在 UTF-8 里是 3 字节

关键区别在于:字符集回答“这个字符的编号是多少”,编码方式回答“这个编号写成几个字节、什么顺序”。 两者是分开的,所以同一段 Unicode 文本可以用 UTF-8 存,也可以用 UTF-16 存。

ASCII 为什么不够用

ASCII 诞生于英文环境,用 7 位表示 128 个字符,刚好够英文字母、数字和常用符号。它的问题很直接:

  • 没有中文、日文、韩文、阿拉伯文、俄文等任何非拉丁字符;
  • 没有 emoji 和大量数学、货币符号;
  • 各国后来各自扩展出本地编码(如 GBK、Shift-JIS、Latin-1),互不兼容。

结果是同一串字节,用不同本地编码解读会得到完全不同的文字——这就是早期中文网页“乱码”的根源。Unicode 的目标就是用一个统一编号表取代这些互不兼容的本地字符集。

为什么同一段文字会乱码

乱码不是字符坏了,而是写入时用的编码和读取时用的编码不一致。

例如“中”这个字:

  • 在 UTF-8 里是 3 个字节:E4 B8 AD
  • 在 GBK 里是 2 个字节:D6 D0

如果文件实际是 UTF-8,但打开时按 GBK 解读,就会显示成“涓”之类的怪字。反过来也一样。UTF-16 与 UTF-8 之间误读,还会出现大量夹杂空字节或问号的情况。

判断和处理的顺序通常是:

  1. 先确认来源:网页看 HTTP 响应头或 <meta charset>;文件看编辑器状态栏或保存选项。
  2. 用工具验证:多数编辑器(VS Code、Notepad++、Sublime)能显示当前编码,并支持“以某编码重新打开”。
  3. 再转换:确认正确编码后,另存为目标编码。命令行可用 iconv -f UTF-8 -t GBK input.txt > output.txt。
  4. 验证结果:重新打开,确认中文、emoji、特殊符号都正常,没有问号或方块。

常见卡点:

  • 只改文件内容里的编码声明,没改实际字节,等于没改;
  • 数据库连接、表、字段三层编码不一致,只改一层仍会乱;
  • 终端本身编码不对,文件正确也会显示乱码。

日常怎么选

  • 网页和新建文件优先用 UTF-8:它兼容 ASCII,英文不浪费空间,又能覆盖全部 Unicode,是当前事实标准。
  • 遇到乱码先查编码声明,不要急着重打内容;多数情况重新按正确编码打开即可恢复。
  • 只在必须对接旧系统时用 GBK 等本地编码,并明确记录,避免后续再次误读。
  • ASCII 仍有用:纯英文场景、日志、协议头里它简单可靠;但一旦涉及多语言,就该交给 Unicode + UTF-8。

一句话记住:Unicode 是“字符名单”,UTF-8 是“把名单写成字节的规则”,ASCII 是这份名单出现之前的英文小册子。 乱码出在规则不匹配,不在名单本身。

brahmi.sourceforge.net
Brahmi: Java Multilingual RTF Word Processor with Java Input Method and OpenType font for Indic Kannada. Brahmi Team: Harsha Ravnikar, Anitha Gowda...
cascii.app
A free, open-source ASCII diagram builder written in vanilla Javascript