zoukankan      html  css  js  c++  java
  • UCS UTF UTF-7 UTF-8 UTF-16

    Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。
    Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。
    UCS可以看作是"Unicode Character Set"的缩写。UCS规定了怎么用多个字节表示各种文字。
    UCS有两种格式:UCS-2和UCS-4。

    顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。
    UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。

    UCS-4根据最高位为0的最高字节分成2^7=128个group。
    每个group再根据次高字节分为256个plane。
    每个plane根据第3个字节分为256行 (rows),
    每行包含256个cells。
    当然同一行的cells只是最后一个字节不同,其余都相同。

    group 0的plane 0被称作Basic Multilingual Plane, 即BMP。
    或者说UCS-4中,高两个字节为0的码位被称作BMP。

    将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。
    在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。
    而目前的UCS-4规范中还没有任何字符被分配在BMP之外。
    UTF(UCS Transformation Format)规范规定怎样传输这些编码,常见的UTF规范包括
    UTF-8、UTF-7、UTF-16。

    UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:
    UCS-2编码(16进制) UTF-8 字节流(二进制) 
    0000 - 007F 0xxxxxxx
    0080 - 07FF 110xxxxx 10xxxxxx
    0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

    例如“汉”字的Unicode编码是6C49
    6C49在0800-FFFF之间,所以肯定要用3字节模板了:
    1110xxxx 10xxxxxx 10xxxxxx。
    将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:
    11100110 10110001 10001001,即E6 B1 89
    UTF-16以16位为单元对UCS进行编码。
    对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。
    对于不小于0x10000的UCS码,定义了一个算法。
    不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。
    但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。
    UTF的字节序和BOM
    UTF-8以字节为编码单元,没有字节序的问题。
    UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。
    例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。
    如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

    Unicode规范中推荐的标记字节顺序的方法是BOM。BOM是Byte Order Mark。BOM是一个有点小聪明的想法:

    在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。
    而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。
    UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。

    这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;
    如果收到FFFE,就表明这个字节流是Little-Endian的。

    因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

    UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。
    字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。
    所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。








  • 相关阅读:
    JavaWeb WebBrowserTool KernelEngine
    类模板 C++快速入门45
    动态数组的使用
    动态数组的使用
    鱼C小甲鱼
    栈原理演示
    鱼C小甲鱼
    类模板 C++快速入门45
    delphi实例
    栈原理演示
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4502027.html
Copyright © 2011-2022 走看看