zoukankan      html  css  js  c++  java
  • Unicode、UTF-8、UTF-16和UTF-32的区别

         Unicode是一个巨大的字符集,给世界上所有的字符定义了一个唯一编码。其仅仅规定了每个符号的二进制代码,没有制定细化的存储规则。UTF-8、UTF-16、UTF-32才是Unicode的存储格式定义。

        

    UTF-8

    Unicode符号范围 | UTF-8编码方式

             (十六进制) | (二进制)

    --------------------+---------------------------------------------

    0000 0000-0000 007F | 0xxxxxxx

    0000 0080-0000 07FF | 110xxxxx 10xxxxxx

    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

    0001 0000-001F FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

    跟据上表,解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;

    如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

     

    Little endian和Big endian

    Unicode码可以采用UCS-2格式直接存储。

    以汉字"严"为例,Unicode码是4E25,需要用两个字节存储,一个字节是4E,另一个字节是25。

    存储的时候,4E在前,25在后,就是Big endian方式;25在前,4E在后,就是Little endian方式。

     

    UCS-2和UCS-4

    Unicode是为整合全世界的所有语言文字而诞生的。任何文字在Unicode中都对应一个值,
    这个值称为代码点(code point)。代码点的值通常写成 U+ABCD 的格式。而文字和代码点之间的对应关系就是UCS-2(Universal Character Set coded in 2 octets)。顾名思义,UCS-2是用两个字节来表示代码点,其取值范围为 U+0000~U+FFFF。

    为了能表示更多的文字,人们又提出了UCS-4,即用四个字节表示代码点。它的范围为 U+00000000~U+7FFFFFFF,其中 U+00000000~U+0000FFFF和UCS-2是一样的。

    要注意,UCS-2和UCS-4只规定了代码点和文字之间的对应关系,并没有规定代码点在计算机中如何存储。规定存储方式的称为UTF(Unicode Transformation Format),其中应用较多的就是UTF-16和UTF-8了。

     

    UTF-16

    UTF-16由RFC2781规定,它使用两个字节来表示一个代码点。

    不难猜到,UTF-16是完全对应于UCS-2的,即把UCS-2规定的代码点通过Big Endian或Little Endian方式直接保存下来。UTF-16包括三种:UTF-16,UTF-16BE(Big Endian),UTF-16LE(Little Endian)。

    UTF-16BE和UTF-16LE不难理解,而UTF-16就需要通过在文件开头以名为BOM(Byte Order Mark)的字符
    来表明文件是Big Endian还是Little Endian。BOM为U+FEFF这个字符。

    其实BOM是个小聪明的想法。由于UCS-2没有定义U+FEFF,因此只要出现 FF FE 或者 FE FF 这样的字节序列,就可以认为它是U+FEFF,并且可以判断出是Big Endian还是Little Endian。

    举个例子。“ABC”这三个字符用各种方式编码后的结果如下:

    UTF-16BE

    00 41 00 42 00 43

    UTF-16LE

    41 00 42 00 43 00

    UTF-16(Big Endian)

    FE FF 00 41 00 42 00 43

    UTF-16(Little Endian)

    FF FE 41 00 42 00 43 00

    UTF-16(不带BOM)

    00 41 00 42 00 43

    Windows平台下默认的Unicode编码为Little Endian的UTF-16(即上述的 FF FE 41 00 42 00 43 00)。
    你可以打开记事本,写上ABC,然后保存,再用二进制编辑器看看它的编码结果。

     

    另外,UTF-16还能表示一部分的UCS-4代码点——U+10000~U+10FFFF。表示算法比较复杂,简单说明如下: 1. 从代码点U中减去0x10000,得到U'。这样U+10000~U+10FFFF就变成了 0x00000~0xFFFFF。
    2. 用20位二进制数表示U'。 U'=yyyyyyyyyyxxxxxxxxxx
    3. 将前10位和后10位用W1和W2表示,W1=110110yyyyyyyyyy,W2=110111xxxxxxxxxx,则 W1 = D800~DBFF,W2 = DC00~DFFF。

    例如,U+12345表示为 D8 08 DF 45(UTF-16BE),或者08 D8 45 DF(UTF-16LE)。

    但是由于这种算法的存在,造成UCS-2中的 U+D800~U+DFFF 变成了无定义的字符。

     

    UTF-32

    UTF-32用四个字节表示代码点,这样就可以完全表示UCS-4的所有代码点,而无需像UTF-16那样使用复杂的算法。
    与UTF-16类似,UTF-32也包括UTF-32、UTF-32BE、UTF-32LE三种编码,UTF-32也同样需要BOM字符。仅用'ABC'举例:

    UTF-32BE

    00 00 00 41 00 00 00 42 00 00 00 43

    UTF-32LE

    41 00 00 00 42 00 00 00 43 00 00 00

    UTF-32(Big Endian)

    00 00 FE FF 00 00 00 41 00 00 00 42 00 00 00 43

    UTF-32(Little Endian)

    FF FE 00 00 41 00 00 00 42 00 00 00 43 00 00 00

    UTF-32(不带BOM)

    00 00 00 41 00 00 00 42 00 00 00 43

  • 相关阅读:
    C# JavascriptSerializer与匿名对象打造Json的完美工具
    C# 跨线程访问或者设置UI线程控件的方法
    使用Windows Live发布博客到博客园
    Ubuntu搭建ssh连接(连接方式:桥接网卡、网络地址转换(NAT))
    SQLServer right函数 从右侧截取指定位数的字符串
    python+MySQL架构
    pip换源(更换软件镜像源)
    Ubuntu搭建mysql,Navicat Premium连接
    一起学习造轮子(三):从零开始写一个React-Redux
    一起学习造轮子(二):从零开始写一个Redux
  • 原文地址:https://www.cnblogs.com/icooper/p/4583684.html
Copyright © 2011-2022 走看看