zoukankan      html  css  js  c++  java
  • 字符集和编码方式

    字符集

    常用字符集分类

    ASCII及其扩展字符集
    作用:表语英语及西欧语言。
    位数:ASCII是用7位表示的,能表示128个字符;其扩展使用8位表示,表示256个字符。
    范围:ASCII从00到7F,扩展从00到FF。

    ISO-8859-1字符集 —— 又称 Latin-1
    作用:扩展ASCII,表示西欧、希腊语等。
    位数:8位,把ascll的最高
    范围:从00到FF,兼容ASCII字符集。

    GB2312字符集
    作用:国家简体中文字符集,兼容ASCII。
    位数:使用2个字节表示,能表示7445个符号,包括6763个汉字,几乎覆盖所有高频率汉字。
    范围:高字节从A1到F7, 低字节从A1到FE。将高字节和低字节分别加上0XA0即可得到编码。

    GBK字符集
    作用:它是GB2312的扩展,加入对繁体字的支持,兼容GB2312。
    位数:使用2个字节表示,可表示21886个字符。
    范围:高字节从81到FE,低字节从40到FE。

    UCS字符集
    作用:国际标准 ISO 10646 定义了通用字符集 (Universal Character Set)。它是与UNICODE同类的组织,UCS-2和UNICODE兼容。
    位数:它有UCS-2和UCS-4两种格式,分别是2字节和4字节。
    范围:目前,UCS-4只是在UCS-2前面加了0×0000。

    UNICODE字符集
    作用:为世界650种语言进行统一编码,兼容ISO-8859-1。
    位数:UNICODE字符集有多个编码方式,分别是UTF-8,UTF-16和UTF-32。

    编码方式

    字符集和编码方式是两个不同的概念,字符集可以看做是一个数字和一个特定形状的字符的映射的关系。而编码方式是将一个字符的Unicode编码转换为二进制的形式。
    utf-8编码方式是使用最广泛的一种编码方式,它是一种动态字节长度的编码方式,将字符集中字符全部进行编码和解码,并且可以根据字符编号对应的大小来改变编码后的字节长度。比如一个"a" 字符在字符集中的编号为97,编码成二进制只需要一个字节长度即可完成,没有必要使用多个字符。


    常见的字符编码方式

    UTF-8的编码规则
    1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
    2)对于N字节的符号,第一个字节的前N位都设为1,第N+1位为0,后面字节的前两位一律设为10。剩下的二进制位,全部为这个符号的unicode码。

    Unicode符号范围 UTF-8编码方式
    (十六进制) (二进制)
    0000 0000-0000 007F 110xxxxx 10xxxxxx
    0000 0080-0000 07FF 110xxxxx 10xxxxxx
    0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
    0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

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


    由于UTF-8这种节省空间的特性,导致它成为互联网上最常见的网页编码。
    比如中文'严'字,二进制表示成:11100100 10111000 10100101
    对应的Unicode code point为 0100 1110 0010 0101对应的HEX值x4E25

    字节和字符的区别

    字节(octet)是一个八位的存储单元,取值范围一定是0~255。而字符(character,或者word)为语言意义上的符号,范围就不一定了。例如在UCS-2中定义的字符范围为0~65535,它的一个字符占用两个字节。

    Big Endian和Little Endian
    上面提到了一个字符可能占用多个字节,那么这多个字节在计算机中如何存储呢?比如字符0xabcd,它的存储格式到底是 AB CD,还是 CD AB 呢?
    实际上两者都有可能,并分别有不同的名字。如果存储为 AB CD,则称为Big Endian;如果存储为 CD AB,则称为Little Endian。
    具体来说,以下这种存储格式为Big Endian(大端模式),因为值(0xabcd)的高位(0xab)存储在前面:
    地址 值

    地址

    0x00000000

    AB

    0x00000001

    CD


    相反,以下这种存储格式为Little Endian(小端模式):

    地址

    0x00000000

    CD

    0x00000001

    AB

    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。可以储存的字符就为65535个

    为了能表示更多的文字,人们又提出了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+FFFE,因此只要出现 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

    另外,UTF-16还能表示一部分的UCS-4代码点——U+10000~U+10FFFF。UCS-2中的 U+D800~U+DFFF 变成了无定义的字符。

    UTF-32


    UTF-32用四个字节表示代码点,这样就可以完全表示UCS-4的所有代码点。与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

    UTF-8

    UTF-16和UTF-32的一个缺点就是它们固定使用两个或四个字节,这样在表示纯ASCII文件时会有很多00字节,造成浪费。而RFC3629定义的UTF-8则解决了这个问题。
    UTF-8用1~4个字节来表示代码点。表示方式如下:

    UCS-2 (UCS-4)

    位序列

    第一字节

    第二字节

    第三字节

    第四字节

    U+0000 .. U+007F

    00000000-0xxxxxxx

    0xxxxxxx

     

     

     

    U+0080 .. U+07FF

    00000xxx-xxyyyyyy

    110xxxxx

    10yyyyyy

     

     

    U+0800 .. U+FFFF

    xxxxyyyy-yyzzzzzz

    1110xxxx

    10yyyyyy

    10zzzzzz

     

    U+10000..U+10FFFF

    00000000-000wwwxx-

    xxxxyyyy-yyzzzzzzz

    11110www

    10xxxxxx

    10yyyyyy

    10zzzzzz

    ​​
    可见,ASCII字符(U+0000~U+007F)部分完全使用一个字节,避免了存储空间的浪费。而且UTF-8不再需要BOM字节。
    另外,从上表中可以看出,单字节编码的第一字节为[00-7F],双字节编码的第一字节为[C2-DF],三字节编码的第一字节为[E0-EF]。这样只要看到第一个字节的范围就可以知道编码的字节数。这样也可以大大简化算法。

  • 相关阅读:
    MySql cmd下的学习笔记 —— 引擎和事务(engine,transaction)
    MySql cmd下的学习笔记 —— 有关视图的操作(algorithm)
    MySql cmd下的学习笔记 —— 有关视图的操作(建立表)
    MySql cmd下的学习笔记 —— 有关常用函数的介绍(数学函数,聚合函数等等)
    MySql cmd下的学习笔记 —— 有关多表查询的操作(多表查询练习题及union操作)
    MySql 在cmd下的学习笔记 —— 有关多表查询的操作(内连接,外连接,交叉连接)
    MySql cmd下的学习笔记 —— 有关子查询的操作(where型,from型,exists型子查询)
    MySql cmd下的学习笔记 —— 有关select的操作(order by,limit)
    剑指Offer--第21题 调整数组顺序使奇数位于偶数前面;
    剑指Offer--和为s的连续正数序列
  • 原文地址:https://www.cnblogs.com/k5210202/p/13068462.html
Copyright © 2011-2022 走看看