Unicode 详解

Posted houhou87

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unicode 详解相关的知识,希望对你有一定的参考价值。

字符集&编码

  • charset 是 character set 的简写,即字符集。
  • encoding 是 charset encoding 的简写,即字符集编码,简称编码。

Unicode (UTF-8 UTF-16 UTF-32) 歧义

由于各种原因,必须承认,在不同的语境下,“Unicode”这个词有着不同的含义,它可能指:

  • Unicode 标准
  • Unicode 字符集
  • Unicode 的抽象编码(编号),也即码点(code point)。
  • Unicode 的一个具体编码实现,通常即为变长的 UTF-16(16 或 32 位),又或者是更早期的定长 16 位的 UCS-2。

编号 编码

  • 字符 <–> 编号 <–> 编码
  • 编号与编码的主要区别在于编号不涉及具体使用多少字节来表示、是用定长还是变长方案等细节问题。编号仅仅是一个抽象的概念,是把字符数字化的一个过程。
  • 字符集 是一组映射关系[字符 - 编号] 具体字符被映射成一个唯一的code--码点 例如:
    • U+[XX]XXXX 是码点的表示形式,X 代表一个十六制数字,可以有 4-6 位,不足 4 位前补 0 补足 4 位,超过则按是几位就是几位。具体范围是 U+0000~U+10FFFF
    • U+0048,U+00E6,U+4F60,U+1D11E(这是个五位的码点)
  • 受编码影响 编号通常也以十六进制形式书写,并保持固定的位数,不够就在前面填充 0,比如把 48 写成 0048;又比如: U+1D11E 就是一个一个五位的编号。
  • 方便扩展,编码常跳过某些码位,甚至保留大片的区域未定义或作保留用途。

小结

  • code point - 码点 - 对字符的数字化抽象 - 不体现具体的编码转换格式
  • 编码 - UTF(Unicode Transformation Format) - Unicode转换格式 - 将抽象的数字转化成具体的编码 - 编码对应[存储字节数、是否变长...]
  • Unicode 的核心就是为每个字符提供唯一一个数字编号。code point 例子: ‘a‘ - 97 - 0061 - U+0061(码点 - 16进制)

    具体编码格式

三种编码方案的定变长与字节数总结:

  • UTF-8:变长,1-4 字节;
  • UTF-16:变长,2 或 4 字节;
  • UTF-32:定长,4 字节。

定长与变长

  • 在容量 和 效率之间全行,出现了变长的编码方案。
  • 默认标示位,变长方案。损失了很多有效码位
  • 出现了代理区 做 区分的 方案

Unicode

  • Unicode 是 Unicode Standard(Unicode标准)的简写,所以 Unicode 即是指 Unicode 标准。
  • 它脱离具体平台、语言,给每一个字符 一个唯一的数字code--码点(code point)
  • 码点的格式 U+[XX]XXXX X:代表一个十六制数字 可以有 4-6 位,不足 4 位前补 0 补足 4 位,超过则按是几位就是几位。以下是码点的一些具体示例:U+0048,U+4F60,U+1D11E。最后一个是5位的码点。
  • 范围[U+0000,U+10FFFF] 理论大小为 10FFFF+1=110000(16进制)[FFFF+1 转10进制 = 65536 ]。是一个百万级别的数。
  • 平面[Plane]为了更好分类管理如此庞大的码点数,把每 65536 个码点作为一个平面,总共 (1 x 16 + 1 )= 17 个平面。
    • first Plane = BMP(Basic Multilingual Plane 基本多语言平面),也叫 Plane 0,它的码点范围是 U+0000 ~ U+FFFF
    • 后续的 16 个平面称为 SP(Supplementary Planes)。范围超过了 U+FFFF即超过了 4个byte了。
    • CJK 统一汉字(CJK:Chinese, Japanese, and Korean,中日韩)在first plane 中间很大一片区域
    • 还有一片空白区域--代理区 这段空白从 D8~DF。其中前面的红色部分 D800–DBFF 属于高代理区(High Surrogate Area),后面的蓝色部分 DC00–DFFF 属于低代理区(Low Surrogate Area),各自的大小均为 4×256=1024。
  • UTF 即是 Unicode 转换格式(Unicode (or UCS) Transformation Format)
    • UTF-32
      • 码点最大的 10FFFF 占 21 位,UTF-32 采用的定长4 byte 则是 32 位。高位补 0 的形式补够 32 位即可,缺点占用空间太大。
      • 4字节 XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
    • UTF-8
      • 变长的编码方案:1,2,3,4 四种 byte 组合
      • 采用高位保留方式 来区别不同变长
        • 1字节 0XXX XXXX
        • 2字节 110X XXXX 10XX XXXX
        • 3字节 1110 XXXX 10XX XXXX 10XX XXXX
        • 4字节 1111 0XXX 10XX XXXX 10XX XXXX 10XX XXXX
      • 码点对应字节
        1. 转二进制,去掉高位0 判断采用几字节
        2. 一字节 有效位7位兼容ASCII [码点] U+0000 ~ U+007F (0~127)
        3. 二字节 11位有效,2^11=2048 个编码空间 码点 U+0080 ~ U+07FF (128~2047)
          • 这里码点从 128~2047,因为去掉了一字节的码点,所以不会占满 2048 个编码空间,是有冗余的,但你不能把适用于一字节的码点放到这里来编码。下同。
        4. 三字节 16位有效,65536 个编码空间 码点U+0800~U+FFFF (2048~65535)
          • 存着绝大部分汉字
        5. 四字节 21位有效,前面说到最大的码点 10FFFF 也是 21 位,U+FFFF 以上的增补平面的字符都在这里来表示。
      • 码点转换
        1. 将码点转换成 2进制
        2. 将二进制数 按照UTF-8 固定位分组
        3. 选中几字节模式后,高位不足 补0
        4. 重新将 2进制数 转换成16进制数
      • N 字节模式,首字节以“N 个 1 再加 0 ”打头,后跟“N-1”个以“10”打头的字节。
    • UTF-16
      • 变长的 2 或 4 字节编码模式
        • BMP内的字符使用 2 字节编码
        • 其它的则使用 4 字节组成所谓的代理对来编码
      • 代理区
        • 鸟瞰图中,一片空白的区域,就是代理区(Surrogate Area),
        • 为了编码增补平面中的字符而保留的,总共有 2048 个位置,均分为高代理区(D800–DBFF)和低代理区(DC00–DFFF)两部分,各1024,这两个区组成一个 二维的表格,共有:1024 × 1024 = 2^10×2^10 = 2^4×2^16 = 16×65536
        • 它恰好可以表示增补的 16 个平面中的所有字符
      • 码点转换
        • BMP 中直接对应,无须做任何转换
        • 增补平面 SP 中:
          1. 减去10000(16进制)[第一个平面中的所有码点]
          2. 除以代理区的行宽[ 1024(10进制) ] 商:第几个高代理区 余数:第几个低代理区
          3.  Lead = (码点 – 10000(16)) ÷ 40016 + D800
             Trail = (码点 – 10000(16) % 40016 + DC00
        • 转换请用API 通过位移运算更高效

以上是关于Unicode 详解的主要内容,如果未能解决你的问题,请参考以下文章

详解Android WebView加载html片段

Unicode 详解

Unicode详解

Unicode 详解

unicode编码详解,一看就懂

Node.js与HTTP响应主体的unicode问题