• 常用编码学习


    常用编码

    在计算机世界,所有信息都是用二进制存储。每一个二进制有0和1两种状态。

    所以8个二进制就可以组合成256种状态,也就是一个字节。

    也就是说,一个字节可以用来表示256种不同的状态,每一个状态对应一个符号,也就是256个符号,从00000000—11111111。

    ASCII码

    一共规定了128个字符的编码,包含大小写字母、数字、还有空格等一些常用符号,这128个符号中有32个不能打印出来的控制符号。只占用了一个字节的后面7位,也就是最前面一位都是0.

    大写字母A是65,也就是二进制的01000001。

    空格是32,也就是二进制的00100000。

    非ASCII编码

    上面讲的ASCII编码规定的128个字符,对英语来说足够用了,但是用来表示其他语言,128个符号不够用。例如,法语字母上面有注音符号,它就无法用ASCII码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。

    比如,法语的é的编码为130,二进制位10000010,这样以来欧洲国家可以使用8个二进制的所有组合,也就是最多256个符号。

    但是,这也有问题,130在法语编码中表示é,而在希伯来语编码中却代表字母Gimel(ג),在俄语编码中又代表另一个符号。但是不管怎样,所有这些编码方式中,0—127表示的符号是不一样的,不一样的只是128—255的这一段。

    至于亚洲国家的文字,额….汉字就10W+,256种符号肯定不够,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是GB2312,使用256个字节表示一个汉字,所以理论上最多表示256*256=65536个符号。

    当然,世界上的编码方式有很多,不止上面提到的这些。

    Unicode

    世界上存在着多种编码方式,同一个二进制数字可以被解释不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

    Unicode是一种把世界上所有符号都纳入其中,每一个符号都给予了一个独一无二的编码,那么乱码问题就会消失。

    Unicode是一个很大的集合,现在的规模可以容纳100多万个符号,每个符号的编码都不一样,比如:

    U+0639表示阿拉伯字母Ain。

    U+0041表示英语的大写字母A

    U+4E25 表示汉字严

    Unicode的问题

    Unicode只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

    例如:汉字转化为二进制是100111000100101,足足有15位,也就是最少需要两个字节,甚至有更大的符号,需要3个字节或者4个字节,甚至更多。

    这就有了两个严重的问题:

    1.如何区分Unicode和ASCII,计算机怎么知道三个字节表示一个符号,而不是表示三个符号呢?

    2.我们已经知道英文字母只用一个字节表示就足够了,如果Unicode同一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必须有2—3个字节是0,这对于数据存储来说是极大的浪费,文本文件的大小因此会打出2—3倍,这是无法接受的。

    UTF-8闪亮登场

    UTF-8Unicode的一种实现方式,其他实现方式还有UTF-16(字符用2—4个字节表示),UTF-32(字符用四个字节表示),不过其他的在互联网上基本不用,UTF-8就是为了统一编码方式产生的,也是互联网上使用最广的一种Unicode的实现方式。

    UTF-8的最大特点,就是它是一种边长的编码方式,可以使用1—4个字节来表示一个符号,根据不同的符号而变化字节长度。

    它的规则很简单,只有两条:

    对于单字节的符号,字节的第一位为0,后面7位为这个符号的Unicode码。因此,对于英文字母,UTF-8和ASCII码是相同的。

    对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律为10。

    汉字的Unicode是4E25(100111000100101),需要用三个字节存储,根据上面的规则,即格式为:

    1110xxxx 10xxxxxx 10xxxxxx

    记住,二进制是从后往前存储的,读也是从后往前读的,所以我们先填充第三个字节,从二进制的后面读取,填充完后变成了:

    1110xxxx 10xxxxxx 10100101

    再根据同样规则填充第二个字节,填充完后变成了:

    1110xxxx 10111000 10100101

    最后填充最后一个字节:

    1110x100 10111000 10100101

    不对啊,怎么少了一个字节?没事,少了的用0补位:

    11100100 10111000 10100101

    Unicode与UTF-8的转换

    这两种编码的转换可以通过程序实现,在Windows平台下,最简单的方法是,通过记事本另存为:

    ACSI就是ACSII,是Windows英文系统的默认的编码格式,但是对于Windows简体中文版默认就是GB2312,针对繁体中文版默认就是Big5。

    而现显示的Unicode都是使用UCS-2编码方式存储的Unicode字节,只不过默认是little endian格式,而另一个选项是Unicode big endian格式。

    Unicode little endianUnicode big endian的转换:

    简单举个例子,UCS-2格式可以存储Unicode码。汉字的Unicode码为4E25,需要用两个字节存储,一个字节是4E,另一个是25。4E在前,25在后就是Big endian(从前往后),25在前,4E在后,就是Little endian(从后往前)。

    那计算机怎么知道某一个文件到底采用哪一种方式编码呢?

    Unicode规范定义,每一个文件最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做 “zero width no-break space” ,用FEFF表示,正好是两个字节。

    如果一个文本文件的头两个字节是FE FF,表示是Big endian方式,如果头两个字节是FF FE,表示是Little endian方式。

    本文大部分来自阮一峰大神的个人博客:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

    Everything has its time and that time must be watched. If you have any question, please contact email linqtosql@qq.com.
  • 相关阅读:
    HTML基础
    JPA+atomikos实现分布式事务
    SpringBoot使用MybatisGenerator操作数据
    Spring data JPA的多数据源实现
    整合Spring Data JPA操作数据及排序分页
    首次git推送到远端
    SpringBoot结合Jpa的post为空和时间问题
    记一次SptingBoot启动报错Error creating bean with name 'requestMappingHandlerAdapter'
    解决IDEA中Cannot resolve table * 的问题
    Sringboot jdbc 操作数据库
  • 原文地址:https://www.cnblogs.com/Fill/p/9581585.html
Copyright © 2020-2023  润新知