Unicode编码机制的历史与理解

ASCII码

在Unicode出现之前,就已经有许多不同的标准存在了,ASCII码就是其中之一,我们都知道计算机所有的信息都以0和1这样的二进制表示,每字节为8bit(这是因为随着发展大家认为8bit可以满足各类字符表示,并在后面受到ASCII码的使用,因此后世默认一字节为8bit),而每位二进制数有 0、1 两种状态,因此 1 字节可以组合出 256 种状态。如果这 256 中状态每一个都对应一个符号,就能通过 1 字节的数据表示 256 个字符。美国人于是就制定了一套编码(其实就是个字典),描述英语中的字符和这 8 位二进制数的对应关系,这被称为 ASCII 码。
ASCII码定义了128个字符,且仅使用了后七位,第一位统一规定为0。

Unicode码诞生的原因

随着网络的发展,虽然ASCII码满足了英语的需求,但用于表示其他语言却显得捉襟见肘,于是一些欧洲国家决定将ASCII码未利用的高位也利用起来,这样就能满足字符不够表达的需求。但这样一来,虽然在0-127号字符大家达成统一,但后128位却千奇百怪,而且随着亚洲语言的加入,这256位能表达的字符显得是那么无力。
人们意识到,需要有一个更高的标准语言来表达这个世界上的所有字符了!
Unicode便在这历史的潮流中诞生

Unicode编码方案

Unicode采用的是16位的字符表达,够是够用了,但却引来了一个问题,占用太大了咋整?

为什么会有占用大这个问题呢,假设A可以用01表示,而* 吴字用0101表示,怎么判断这个0101不是两个A*组成呢?对了,那就是所有字符我们都用4位来表示,A可以往前边加0,用0001表示,对吧。这样新的问题就来了,本来两位就能表达的字符现在用4位才能表达,凭空多了两位出来,一个两个没什么,数千个字符加入进来,这就造成了空间的极大浪费。所以为了解决Unicode编码问题,UTF-8和UTF-16这两种编码方式就诞生了,虽然也有UTF-32,但使用程度没有上述两个广泛。

UTF-8

UTF-8很好的实现了对ASCII码的兼容,以此保证了Unicode被大众接受的基础。
UTF-8 是目前互联网上使用最广泛的一种 Unicode 编码方式,它的最大特点就是可变长度。它可以使用 1 - 4 个字节表示一个字符,根据字符的不同变换长度。编码规则如下:

  1. 对于需要使用 N 个字节来表示的字符(N > 1),第一个字节的前 N 位都设为 1,第 N + 1 位设为0,剩余的 N - 1 个字节的前两位都设位 10,剩下的二进制位则使用这个字符的 Unicode 码点来填充。
  2. 对于需要使用 N 个字节来表示的字符(N > 1),第一个字节的前 N 位都设为 1,第 N + 1 位设为0,剩余的 N - 1 个字节的前两位都设位 10,剩下的二进制位则使用这个字符的 Unicode 码点来填充。

😐

Unicode 十六进制码点范围UTF-8 二进制
0000 0000 - 0000 007F0xxxxxxx
0000 0080 - 0000 07FF110xxxxx 10xxxxxx
0000 0800 - 0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000 - 0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-16

此编码方式是以平面为载体,Unicode将全世界所有的字符定义在一个集合里。这么多的字符不是一次性定义的,而是分区定义。每个区可以存放 65536 个(2^16)字符,称为一个平面(plane)。

目前,一共有 17 个(2^5)平面,也就是说,整个 Unicode 字符集的大小现在是 2^21。

最前面的 65536 个字符位,称为基本平面(简称 BMP )

它的码点范围是从 0 到 2^16-1,写成 16 进制就是从 U+0000 到 U+FFFF
。所有最常见的字符都放在这个平面,这是 Unicode 最先定义和公布的一个平面。

剩下的字符都放在辅助平面(简称 SMP )

码点范围从 U+010000 到 U+10FFFF。

它的编码规则很简单:基本平面的字符占用 2 个字节,辅助平面的字符占用 4 个字节。也就是说,UTF-16 的编码长度要么是 2 个字节(U+0000 到 U+FFFF),要么是 4 个字节(U+010000 到 U+10FFFF)。

那么曾经的问题来了,当我们遇到两个字节时,到底是把这两个字节当作一个字符还是与后面的两个字节一起当作一个字符呢?

这里有一个很巧妙的地方,在基本平面内,从 U+D800 到 U+DFFF 是一个空段,即这些码点不对应任何字符。因此,这个空段可以用来映射辅助平面的字符
辅助平面的字符位共有 2^20 个,因此表示这些字符至少需要 20 个二进制位。UTF-16 将这 20 个二进制位分成两半,前 10 位映射在 U+D800 到 U+DBFF,称为高位(H),后 10 位映射在 U+DC00 到 U+DFFF,称为低位(L)。这意味着,一个辅助平面的字符,被拆成两个基本平面的字符表示。

因此,当我们遇到两个字节,发现它的码点在 U+D800 到 U+DBFF 之间,就可以断定,紧跟在后面的两个字节的码点,应该在 U+DC00 到 U+DFFF 之间,这四个字节必须放在一起解读。

本文为笔者参考以下内容结合自身理解编写,原博有更详细的说明和例子,可移步观看crazyYong的博客

望共同进步,peace!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值