首页 > 其他分享 >编码之ASCII,UTF-8(Unicode),GBK,GB2312

编码之ASCII,UTF-8(Unicode),GBK,GB2312

时间:2022-10-09 07:11:05浏览次数:53  
标签:编码 UTF 字节 字符 字符集 GBK GB2312 0000 ASCII

编码之ASCII,UTF-8(Unicode),GBK,GB2312

编码

计算机中的编码,通俗的讲就是字符怎样在计算机中的表示和存储。要弄明白编码,就要清楚这里的表示和存储这两个概念:

表示,也就是说的各种字符集(ASCII字符集,GBK字符集等),一般由码位和字符组成,其实就是字符和码位的映射。

存储,也就是如何将字符集中的字符存储在计算机中里面

直接举例来说:

ASCII编码

ASCII编码由美国人发明,它采用ASCII字符集,包含了以下128个字符:

可见字符(共95个):包含小写的英文字母,数字,标点符号。

不可见字符(也称为控制字符,共33个):包含空格,换行,标题开始,正文开始,回车等

ASCII字符集如下图所示

image

有了字符集(表示),我们就可以来说一下存储了:ASCII编码的存储规则很简单,就是直接将每个字符对应的码位转换成二进制信息进行存储,由于128个码值(0-127)用7位就可以表示(2^7=128),但计算机的存储单位1个字节由8位组成,所以就直接用8位表示了,即从0000 0000 到 0111 1111,共128个,这样的二进制信息就叫作ASCII码。

扩展ASCII编码

后来,计算机传到了欧洲,欧洲的国家发现ASCII字符集里面并没有包含他们欧洲国家使用的一些字符,而且,8位的ASCII字符集实际上只用了7位,索性就在原有的ASCII码上进行扩展(增加了1000 0000 到 1111 1111,128个字符),这新增的128个字符就叫作扩展ASCII字符集,当然存储规则并没有变。

GB2312编码

再后来,计算机来到了中国,我们发现这1个字节表示的256字符根本没有中文啊,1个字节就能表示256个字符,这怎么够用。索性我们自己设计一个编码吧,我们就叫它GB2312(国标2312)。首先,先设计字符集,我们使用了分区管理的方法,将字符集分为94个区(有些区是空的),每个区含有94个码位(字符),共计8836个字符。如下是57区:
image

码位怎么表示呢?我们可以看到,侃字位于第57区,第0行,第9列,所以侃字的码位就是5709。这样我们就有了每个字符和其对应的码位(字符集),接下来就可以谈存储了!它的存储规则如下,以侃字为例,将其码位5709,先分为57和09两部分,然后分别用其十六进制加上0xA0,然后再合并:57的十六进制是0x39,和0xA0相加是0xD9,09的十六进制是0x09,和0xA0相加是0xA9。所以侃这个字最终的GB2312码为0xD90xA9(D9A9)。至于问什么要这么存储,有兴趣的可以自行百度一下。

GBK编码

后来随着汉字增加,原有的GB2312字符集也不够用了,所以又对其进行了扩充,将之前94个区保留的空的区也用上,存储规则也发生了一些改变(具体不再赘述),就形成了GBK编码。(其实后来又对GBK进行了扩充,就出现了GB18030编码)

Unicode标准

再后来由于各个国家都设计自己的字符集,太乱了。。。ISO就看不下去,是时候管管了,干脆来一个大集合,把世界上所有的字符都包含进去,然后编上号。所以,Unicode(万国码)就诞生了,这里Unicode其实是个标准,它包含了字符集以及对应的编码规则。最开始Unicode使用UCS-2字符集(16位,能表示65536个字符),将码位对应的二进制直接存储。但65536个字符还是无法cover住世界上所有的字符。后来出现了USC-4字符集(32位,能表示近43亿个字符,连emoji都放进去了),然后将码位对应的二进制直接存储,这下总算是能放下了。但是!!!英文人家只要8位就够了,我们中文只要16位就够了,你这直接整了32位,也太浪费了吧。所以就出现了接下来UTF-8这个编码规则!!!

UTF-8编码

它是一种可变长编码格式,每次传输8位数据。可以将其理解为Unicode标准的一种实现:

UTF-8将USC-4字符集的码位,划分为4个区间:

码位                   |        UTF-8编码方式(存储方式)
(十六进制)              |              (二进制)
--------------------------------------------------------------------
0000 0000 - 0000 007F | 0xxxxxxx(0开头,表明该字符由1个字节)
0000 0080 - 0000 07FF | 110xxxxx 10xxxxxx(2个1开头,表明该字符由2字节表示)
0000 0800 - 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx(3个1开头,表明该字符由3字节表示)
0001 0000 - 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(4个1开头,表明该字符由4字节表示)

使用方法举例(存储规则):

如王这个字,它在USC-4字符集里面的码位是 0000 738B,它属于第三区间,将其转化为二级制为 0000 0000 0000 0000 0111 0011 1000 1011,由于属于第三区间,则将其二进制表示的码值,按从右往左的顺序插入到 1110xxxx 10xxxxxx 10xxxxxx 中,最后的结果就是 11100111 10001110 10001011,这就是王字的UTF-8码值,转换为16进制的表示形式为 0xe7 0x8e 0x8h(e78e8h)。

番外篇:“锟斤拷”、“烫烫烫”、“屯屯屯”

“锟斤拷”

一般在UTF-8和中文编码(如GBK)的转换过程中产生。Unicode所使用的字符集中有一个特殊的替换符号,你一定见过,如下所示,专门用于表示无法识别或者无法展示的字符:

image

“烫烫烫”和“屯屯屯”

这种乱码最常见的地方是Visual Studio里。Visual Studio中,未初始化的栈空间用0xCC填充,而未初始化的堆空间用0xCD填充。而0xCCCC和0xCDCD在中文GB2312编码中分别对应“烫”字和“屯”字。如果一个字符串没有结束符’\0’,输出时就会打印出未初始化的栈或堆空间的内容,这就是大名鼎鼎的“烫烫烫”、“屯屯屯”乱码。

所占字节数

  • 1,ASCII码:一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字度节的空间。

  • 2,UTF-8编码:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。中文标点占三个字节,英文标点占一个字节

  • 3,Unicode编码:一个英文等于两个字节,一个中文(含繁体)等于两个字节。中文标点占两个字节,英文标点占两个字节

  • 4,GBK编码:中文2个字节,英文1个字节;

标签:编码,UTF,字节,字符,字符集,GBK,GB2312,0000,ASCII
From: https://www.cnblogs.com/Tiger-Wang-Ai-hu/p/16770859.html

相关文章

  • python 报错“UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte“的解决办法
    用python读取一个txt文件withopen(file,encoding='utf-8')asf:conlines=f.readlines()运行报错:UnicodeDecodeError:‘utf-8’codeccan’tdecode......
  • 字符编码 XUTF
    /**Copyright(c)HuaweiTechnologiesCo.,Ltd.2019-2020.Allrightsreserved.*Description:上机编程认证*Note:缺省代码仅供参考,可自行决定使用、修改或删除......
  • 简单MD5加密工具-UTF-8
    importjava.io.UnsupportedEncodingException;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.time.LocalDateTime......
  • java中如何在ISO-8859-1和UTF-8之间相互转换呢?
    我们都知道在一些特殊的场景,我们需采用特殊的编码格式,如:UTF-8,但是系统默认的编码为ISO-8859-1那么我们就需要将编码转换为我们所需的编码格式,今天我就遇到这个问题,需要......
  • python文件读取错误UnicodeDecodeError: 'utf-8' codec can't decode byte 0x92 in po
    参考:https://segmentfault.com/q/1010000004268196/a-1020000004269556ubuntu下Python3使用open('filename','r').read()读取.txt文件时抛出异常:UnicodeDecodeError......
  • utf8 转码为gbk
    使用场景:有些培训资料放nginx中,通过浏览器观看,但linux中使用的是utf-8编码,浏览器使用的是gdk编码解决方法:linux中下载convmv包  aptinstallconvmvlinux中创建中文目......
  • 字符编码笔记:ASCII,Unicode 和 UTF-8
    一、ASCII码我们知道,计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说......
  • qt报“Error:Could not decode “xxx“ with“UTF-8“
     qt里导入vs里创建的一个包含中文注释的头文件,中文注释显示为乱码,并报错“Error:Couldnotdecode“xxx“with“UTF-8“,editingnotpossible”解决办法:点击文件上......
  • utf8和utf8mb4的区别
     https://blog.csdn.net/grl18840839630/article/details/105597074/ 一、导读我们新建mysql数据库的时候,需要指定数据库的字符集,一般我们都是选择utf8这个字符集,但是......
  • mysqlbinlog 查看binlog时报错unknown variable 'default-character-set=utf8'【转】
    下午在排查MySQL主从同步问题时,想从主库的binlog中找一些线索,裸的binlog文件是无法直视的,mysqlbinlog这个工具是用来查看binlog文件内容的(使用方式manmysqlbinlog查看),但是......