什么是UTF?


UTF是UCS转换格式的缩写。UCS是通用字符集的缩写。通用字符集与Unicode标准同步。存在三种常见的UTF编码类型,即UTF-8,UTF-16和UTF-32。

UTF-8将Unicode字符编码为8位值的序列,称为代码单元。在UTF-8中,编码单位为8位长。同样,UTF-16和UTF-32各自使用16位和32位来编码Unicode字符。

当前版本的Unicode标准中包含超过143千个字符(在撰写本文时,v13.0是标准)。Unicode字符的代码点的有效范围是0到10FFFF(以十六进制表示)。在此代码点范围之外,从D800到DFFF的范围内的值保留用于创建代理对,并且未分配给任何抽象字符。D800–DBFF(Hex)范围适用于高代理,而DC00–DFFF(Hex)范围适用于低代理。该代理用于使用UTF-16编码对补充字符进行编码,这将在本文后面进行讨论。让我们看看如何完成UTF-8编码。

在UTF-8编码中,根据要编码的字符的值,将单个Unicode字符编码为多个八位字节。下表显示了用于对不同代码点范围内的字符进行编码的字节数或(代码单位):

Code Point Values (Hex) No. of Code Units (bytes)
0 – 7F 1
80 – 7FF 2
800 – FFFF 3
10000 – 10FFFF 4

对于7位值(0–7F),将对代码点进行编码并存储在具有代码点值的单个字节中,即,将单个0比特的字节与7位代码点值存储在一起。要编码的7位编码如下所示:

第一个字节= 0xxxxxxx,其中xxxxxxx是要编码的7位。

对于11位值(80–7FF),代码点被编码为2个字节,其中第一个字节的最高3位设置为110,其后是代码点值的最高5位,第二个字节将初始的2位设置为10,然后是11位代码点值的最低有效6位。第一个字节的最高有效3位中的110表示它是2字节编码的第一个字节,第二个字节的最高有效2位中的10表示它是一个连续字节。现在,将要编码的11位编码如下:

第一个字节= 110mmmmm,其中mmmmm是要编码的11位中最高的5位(10-6位),

第二个字节= 10nnnnnn,其中nnnnnn是要编码的其余6位(位5-0)。

对于16位值(800–FFFF),代码点被编码为3个字节,其中第一个字节的最高4位被设置为1110,然后是代码点值的最高4位。第二个字节的初始2位设置为10,后跟16位代码点值的后6位,第三个字节的初始2位设置为10,后跟最低有效位6。 16位代码点值。第一个字节的最高4位中的1110表示它是3字节编码的第一个字节,接下来的两个字节将初始2位设置为10,以指示这是连续字节。现在,要编码的16位编码如下:

第一个字节= 1110wwww,其中wwww是要编码的16位中最高的4位(15-12位),

第二个字节= 10xxxxxx,其中xxxxxx是接下来要编码的6位(11-6位),

第三个字节= 10yyyyyy,其中yyyyyy是要编码的其余6位(位5-0)。

对于21位值(10000–10FFFF),代码点被编码为4个字节,其中第一个字节的最高5位设置为11110,然后是代码点值的最高3位,第二个字节具有最初的2位设置为10,后跟21位代码点值的下一个6位,第三个字节的初始2位设置为10,后跟21位代码点值的下一个6位值,第四个字节为10,后跟21位代码点值的最低有效6位。第一个字节的最高5位中的11110表示它是4字节编码的第一个字节,接下来的三个字节将初始2位设置为10,以指示这些是连续字节。要编码的21位未按以下方式编码:

第一个字节= 11110www,其中www是要编码的21位中最高的3位(20-18位),

第二个字节= 10xxxxxx,其中xxxxxx是接下来要编码的6位(17-12位),

第3个字节= 10yyyyyy,其中yyyyyy是接下来要编码的6位(11-6位),

第4个字节= 10zzzzzz,其中zzzzzz是要编码的其余6位(位5-0)。

这显示了如何使用标准UTF-8编码对Unicode字符进行编码。

标准UTF-8编码有一个变体,称为修改的UTF-8。Java中的writeUTF和readUTF方法在Java中使用此变体,该方法出现在DataOutputStream,DataInputStream和RandomAccessFile类中。根据对零进行编码时的变化,使用11位编码将其编码为2个字节,这将产生2个字节11000000 10000000(C0 80 Hex)。这样做是为了确保所有位= 0在此编码中都不是有效字节。关于第四范围内的值的另一变化。在对补充字符进行编码时,任何补充字符都可以作为2个字符值使用(高替代然后低替代)。这导致这些字符每个被编码为6个字节(高代理3个字节,低代理3个字节)。

现在让我们看一下UTF-16编码。

对于UTF-16编码,根据代码点的值,Unicode字符将被编码为一个16位代码单元或两个16位代码单元。我们知道Unicode字符的代码点范围是从0到10FFFF(十六进制)。从0到FFFF(十六进制)范围内的字符被编码到单个16位代码单元中,并按原样保留字符的值。从0到FFFF(十六进制)范围内的字符是BMP(基本多语言平面)中的字符。范围从10000(十六进制)到10FFFF(十六进制)的补充字符被编码为两个16位值,在下面说明。

要对范围在(10000-10FFFF)范围内的任何代码点进行编码,第一步是从代码点的值中减去100000(十六进制)。现在,结果值的范围为0到FFFFF(十六进制),它是20位数字。现在,将这20位编码为两个16位值,如下所示。

第一个16位代码单元的初始6位将设置为110110,然后通过从初始代码点值中减去10000(Hex)得出20位值中的最高有效10位,以及第二个16位代码单元的初始6位设置为110111,然后通过从初始代码点值中减去10000(Hex)得出20位值的最低有效10位。因此,20位的编码如下所示:

第一个16位代码单元= 110110xxxxxxxxxx,其中xxxxxxxxxx是要编码的20位中最高的10位(19-10位),

第二个16位= 110111yyyyyyyyyy,其中yyyyyyyyyy是要编码的20位中的其余10位(9-0位)。

因此,第一个代码单位的范围是1101100000000000到1101101111111111111(D800–DBFF),这是高代理范围,而第二个代码单位的范围是1101110000000000到1101111111111111(DC00–DFFF),即低代理的范围。

这显示了如何使用UTF-16编码对Unicode字符进行编码。


原文链接:http://codingdict.com