zoukankan      html  css  js  c++  java
  • 第十二篇 字符编码

    第十二篇 字符编码

    # 预备知识

    由于计算机语言是一组高低电平,高电平代表1,低电平代表0,计算机中的所有信息都是以二进制代码的形式存在的,无论是文字、图片、声音,还是影像、游戏......

    ASCII:美国信息交换标准码(American Standard Code for Information Interchange)

    类似于摩斯电码,为了让人们能看懂这些二进制代码,美国人最先制定了一种编码规则——ASCII码,用于理解二进制代码到底代表的是哪些字符,ASCII码使用指定的7个二进制位组合,这些组合所能表示的128个整数用来代表大小写字母、0到9的数字、控制字符、通信专用字符、空格符、运算符号、标点符号等的编号,通过编号可以找到一一对应的字符,ASCII码通常会额外使用一个扩充的二进制位,虽然这个二进制位可能并不代表任何意思,但是可以方便以一个字节的方式存储每个字符

    在美国计算机装的英文系统上的编码表可能是ASCII码也可能是EBCDIC码,而编码格式也一定是ASCII编码格式,才能在输出文本和打开文本时不出现乱码

    GBK:汉字字符集国家标准编码

    ASCII码只能满足英文在计算机上通信的需要,为了扩充ASCII编码,也为了满足其他语言的通信需要,各国也都制定了各自的属于本国语言的字符编码来方便在计算机上通信,例如我国的GBK

    在GBK编码体系下,有些字符使用双字节组合来表示,需要知道GBK编码标准兼容GB2312,GB2312采用了二维矩阵编码法对所有字符进行编码,它是一个94行94列的方阵,对每一行称为一个“区”,每一列称为一个“位”,然后将所有字符依照编码表的规律填写到方阵中。这样所有的字符在方阵中都有一个唯一的位置,这个位置可以用区号、位号合成表示,称为字符的区位码。如第一个汉字“啊”出现在第16区的第1位上,其区位码为1601。因为区位码同字符的位置是完全对应的,因此区位码同字符之间也是一一对应的。这样所有的字符都可通过其区位码转换为数字编码信息
    GBK编码中,每个字节的第一个二进制位会被当做标志位,标志位为1则表示是中文字符,标志位为0则表示为英文字符

    ANSI(American National Standards Institute,美国国家标准协会):ANSI编码格式(又称MBCS:Muilti-Bytes Charecter Set,多字节字符集)

    为了使计算机支持更多的语言,Windows(也可能是美国别的某机构)制定了一种编码格式——ANSI编码格式(又称MBCS:Muilti-Bytes Charecter Set,多字节字符集),这个ANSI编码收录了中国制定的GBK编码,所以在计算机上装的“简体中文Windows系统”中使用的ANSI编码格式就是GBK编码,而在日本装的日文Windows系统中使用的ANSI编码格式就是Shift_JIS编码

    Unicode:统一的字符编码标准

    虽然各国都有自己的字符编码,但是却无法在计算机上互通,因为在制定编码的时候,都有各自的编码规则,有可能两个国家使用了相同的二进制组合却代表的是各自国家语言的不同字符。为什么有时候电子邮件和网页都经常会出现乱码,就是因为信息的提供者可能是日文的ANSI编码体系,而信息的读取者可能是中文的编码体系,他们对同一个二进制编码值进行显示,采用了不同的编码,导致乱码。这个问题促使了unicode码的诞生

    Unicode是一个很大的字符编码规则,它收录了中文、英文、日文还有别的各种国家的语言的编码表。Unicode是一个庞大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如:U+0041表示英语的大写字母A,“汉”这个字的Unicode编码是U+6C49
    在我们编写代码时,可以在赋值的时候利用“U+ ”的方法,比如在pycharm中

    x = u'你是我のgirl friend'
    ##这个“x”是Unicode格式的数据,无论怎么打印,都不会乱码
    

    Unicode固然统一了编码方式,但是它的效率不高,比如UCS-4(Unicode的标准之一)规定用4个字节存储一个符号,那么每个英文字母前都必然有三个字节是0,这对存储和传输来说都很耗资源。而不这样规定的话,有的字符是一个字节,有的字符是两个字节组合,计算机在读取的时候就不知道按照那种规则读取内容了,就会造成乱码,所以Unicode虽然结决了这种问题,但是如果存储的话可能会对内存造成很大的浪费而且读取的速度也会比较慢,这样就需要一种存储规则,将写好的Unicode编码转换成占内存较小的编码格式,解决读写问题

    UTF-8 :8-bit Unicode Transformation Format(8字节Unicode转换格式)

    utf-8是一种编码规则,是为了更好的存储和读取用Unicode编写的编码

    utf-8可以将原本的Unicode码进行transformation(转换),这种转换就是给每个Unicode码进行标记,使得让计算机看到某个标记就知道待会要读取几个字节的代码

    • UTF-8的编码规则很简单,只有二条:
    1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的
    2. 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码
    3. 比如汉字字符“啊”,它在GBK中的区位码是1601,我们可以看它用GBK、Unicode、utf-8如何写成
    编码规则 二进制代码
    GBK 1001 0110 1000 0001
    Unicode/UCS-4 0000 0000 0000 0000 xxxx xxxx xxxx xxxx
    UTF-8 1101 0110 1000 0001

    # 其实ASCII、GBK、Shift_JIS这些都是字符集,将它们转换成计算机能看懂的二进制编码(或者计算机将二进制编码转换成这些字符集所对应的字符)的过程就是字符编码的过程

    # Unicode是一种编码标准,目前计算机编写代码都是按照Unicode规定的格式在编写,它收录了ASCII和ANSI中所有的编码表

    1 保证不乱码的前提就是,字符按照什么标准而编码的,就要按照什么标准解码,这里的标准就是字符编码

    2 在内存中写的所有字符都是Unicode编码,我们唯一能改变的就是存储到硬盘时使用的编码(一般是UTF-8)

    • (内存)Unicode -------> encode(编码)--------> (硬盘)GBK
    • (硬盘)GBK -------> dncode(编码)--------> Unicode(内存)

  • 相关阅读:
    力扣238.除自身以外数组的乘积 & 剑指offer 51.构建乘积数组
    网易的Airtest
    ZOOKEEPER
    Apache和Nginx负载均衡集群及测试分析
    mysql——创建索引、修改索引、删除索引的命令语句
    sql-索引的作用
    ADB连接手机的两种方式(usb数据线连接和wifi连接)
    adb shell dumpsys 命令
    count(*) 和 count(1)和count(列名)区别
    博客园页面设置
  • 原文地址:https://www.cnblogs.com/itboy-newking/p/10851892.html
Copyright © 2011-2022 走看看