gpt4 book ai didi

字符编码:Unicode&UTF-16&UTF-8

转载 作者:我是一只小鸟 更新时间:2023-01-01 06:31:06 25 4
gpt4 key购买 nike

ASCII码

使用一个字节(8位),对128个字符进行编码; 。

最高位始终为0; 。

码数范围为 0000_0000(0x00) 到 0111_1111(0x7F) ; 。

Unicode

开始的编码设计

使用两个字节(16位),对65536个字符进行编码; 。

范围为 0000_0000_0000_0000(0x0000) 到 1111_1111_1111_1111(0xFFFF) ; 。

而 0x0000 - 0x007F 对应的字符,与ASCII码保持一致; 。

最终的编码设计

由于世界上的字符,超过了65536个,所以开始只用两个字节的设计已经不足够了,需要扩展; 。

最终扩展如下:

  • 基本多语言平面(BMP, Basic Multilingual Plane) 。

    和开始的设计一致,用两个字节来编码,码数范围 0x0000 - 0xFFFF ; 。

    但是,在这个范围里,有预留 0xD800 - 0xDFFF 的码数,他们不代表任何字符,仅用于作为增补平面的代理对而存在; 。

  • 增补平面(SP, Supplementary Plane) 。

    超出 BMP 所能表示的字符,改用如下范围: 0x10000 - 0x10FFFF 来编码; 。

    Unicode编者认为这个范围已经足够全世界的字符编码了,因为这足够表示一百万多个字符了; 。

代理对(surrogate pair)

预留的 0xD800 - 0xDFFF ,分为两部分:

  • 高位 0xD800 - 0xDBFF
  • 低位 0xDC00 - 0xDFFF

这样做的目的,是为了UTF-16编码方式; 。

一个高位加一个低位,共四个字节,定义了SP中的字符的UTF-16编码; 。

码点(code point)

Unicode编码中,一个字符所对应的码数,称为该字符的码点; 。

通常在计算机的字符和字符串中,使用 \u码点 的形式来转义码点,来表示一个Unicode编码的码点所对应的字符; 。

UTF-16

请注意,Unicode编码的码点,是人为约定的对字符的编码方式; 。

但是计算机只认二进制,所以如何将Unicode定义的字符的码点,编码为计算机实际存储的二进制串,以及如何从一串二进制串,解码成Unicode定义的字符的码点,就是 UTF-16 要做的事情; 。

UTF-16的16代表最小的编码单位是16位二进制串; 。

编码

分为两种情况:

  • BMP中的字符 。

    直接用Unicode定义的码点作为UTF-16编码即可; 。

  • SP中的字符 。

    使用两个16位二进制串进行编码,即采用四个字节来编码; 。

    现在假设有一个字符,其Unicode定义的码点为 0xAAAAA ,对其进行如下操作:

    • u = 0xAAAAA - 0x10000;
    • 将u写成二进制串: yyyy_yyyy_yyxx_xxxx_xxxx
    • 则该字符的UTF-16编码为: 1101_10yy_yyyy_yyyy 1101_11xx_xxxx_xxxx

    SP 的UTF-16编码的两个16位二进制串:

    第一个16位串的前六位固定是 1101_10 ,结合 yy 的范围( 00 - 11 ),即 1101_1000 - 1101_1011 ,此范围即是代理对的高位的前两位 0xD8 - 0xDB ; 。

    第二个16位串的前六位固定是 1101_11 ,结合 xx 的范围 00 - 11 ,即 1101_1100 - 1101_1111 ,此范围即是代理对的低位的前两位的范围 0xDC - 0xDF ; 。

    再结合各自后面八位二进制串的范围 0000_0000 - 1111_1111 ,就可以得到各自完整的代理对; 。

    也就是说, SP 的UTF-16的编码结果,即为高位+低位的四个字节的代理对; 。

解码

只要看一个16位二进制串的头八位,是否在代理对的范围即可; 。

  • 不在代理对的范围 。

    说明是 BMP 中的字符,直接对应Unicode码点找到对应的字符即可; 。

  • 在代理对的范围 。

    说明是 SP 中的字符,再根据头六位确定好代理对的高低位, 。

    去除各自的前六位,组成20位二进制串,再加上 0x10000 即为Unicode定义的码点,即可找到对应的字符; 。

UTF-8

UTF-8是不同于UTF-16的另一种对Unicode的编解码方式; 。

不同之处就在于,UTF-8的8代表最小的编码单位是8位二进制串; 。

编码

UTF-8对码点的编码方式如下:

  • 码点范围 0x0000 - 0x007F 。

    UTF-8编码为二进制串 0xxx_xxxx ,与ASCII码保持一致,长度为1个字节; 。

  • 码点范围 0x0080 - 0x07FF 。

    UTF-8编码为二进制串 110x_xxxx 10xx_xxxx ,长度为2个字节; 。

  • 码点范围 0x0800 - 0xFFFF 。

    UTF-8编码为二进制串 1110_xxxx 10xx_xxxx 10xx_xxxx ,长度为3个字节; 。

  • 码点范围 0x10000 - 0x10FFFF 。

    UTF-8编码为二进制串 1111_0xxx 10xx_xxxx 10xx_xxxx 10xx_xxxx ,长度为4个字节; 。

假设现在有一个字符,码点在范围 0x0800 - 0xFFFF 中:

  • 将其码点写成二进制串: xxxx_yyyy yyzz_zzzz
  • 则UTF-8编码的第一个字节为 1110_xxxx ;
  • 第二个字节为 10yy_yyyy
  • 第三个字节为 10zz_zzzz

解码

只要看第一个字节的首位即可:

  • 首位为0 。

    说明在码点范围 0x0000 - 0x007F ,直接对应Unicode码点找到对应的字符即可; 。

  • 首位为1,再看从首位开始,遇到第一个0结束,一共有几个1 。

    • 两个1,说明UTF-8编码长度为2个字节
    • 三个1,说明UTF-8编码长度为3个字节
    • 四个1,说明UTF-8编码长度为4个字节
    • 去除对应字节的固定位,组合为一个二进制串,找到对应Unicode码点的字符即可;

代码单元(code unit)

不同的UTF编码,所对应的编码单位的长度不同; 。

UTF-16的编码单位的长度为16位二进制; 。

UTF-8的编码单位的长度为8位二进制; 。

这个编码单位称为代码单元; 。

比如对于UTF-16的编码:

在 BMP 中,一个字符所对应的UTF-16的16位二进制串,称为该字符的代码单元; 。

而在 SP 中,一个字符所对应的UTF-16的两个16位二进制串,称为该字符的一对代码单元; 。

而对于UTF-8的编码:

在码点范围 0x0000 - 0x007F 中,一个字符所对应的UTF-8的4个字节,称为该字符的4个代码单元; 。

在码点范围 0x0080 - 0x07FF 中,一个字符所对应的UTF-8的4个字节,称为该字符的4个代码单元; 。

在码点范围 0x0800 - 0xFFFF 中,一个字符所对应的UTF-8的4个字节,称为该字符的4个代码单元; 。

在码点范围 0x10000 - 0x10FFFF 中,一个字符所对应的UTF-8的4个字节,称为该字符的4个代码单元; 。

也就是说,随着UTF编码形式的不同,同一个字符的码点,会有不同个数的代码单元; 。

最后此篇关于字符编码:Unicode&UTF-16&UTF-8的文章就讲到这里了,如果你想了解更多关于字符编码:Unicode&UTF-16&UTF-8的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com