0
点赞
收藏
分享

微信扫一扫

计算机中的字符编码

奔跑的酆 2021-09-30 阅读 101
日记本

计算机只能处理二进制的数据,其它形式的数据都只能转换为二进制后才能被cpu处理及存储。转换就涉及到要有一套字符编码,即字符与二进制的对应关系。

1. ASCII 编码

全称American Standard Code for Information Interchange 美国信息交换标准代码,上个世纪60年代,美国制定的一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。ASCII用1个字节(8位二进制)来表示一个字符,因此八个二进制位就可以组合出256种状态(从0000000到11111111),但ASCII码一共规定了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0。比如:字母a,用二进制表示01100001(十进制值为97)。

2. Unicode

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

若有一种编码,将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码,就可以解决乱码问题,Unicode应运而生。

Unicode编码集合可以容纳100多万个符号,每个符号的编码都不一样。比如U+0042表示英语的大写字母"B",U+1F600表示"?",U+8DF3表示汉字"跳"。具体的符号对应表,可以查询unicode.orgUnicode Utilities或者专门的汉字对应表

3. UTF-8

UTF-8是Unicode的实现方式之一,这种Unicode/UTF-8统一编码方式有利于数据的传输和计算机科学的发展。其他实现方式还包括UTF-16(字符用两个字节或四个字节编码)和UTF-32(字符用四个字节编码),不过在互联网上基本不用。

也就是说,UTF-8编码是一种变长的编码,它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

在Mac上创建一个txt文档,在偏好设置中,能够选择当前文档的存储编码方式,也可进行编码之间的转换:

4. 编码中的Little endian和Big endian

若将一个十六进制数据"8DF3"直接进行存储,需要用两个字节存储,一个字节是8D,另一个字节是F3。那么,计算机在存储空间的地址顺序上,是将8D在前,还是将F3在前呢?

Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。

如果一个文本文件的头两个字节是FE FF,就表示该文件采用大端序;如果头两个字节是FF FE,就表示该文件采用小端序。

新建一个记事本文本文件,输入一个汉字作为内容,依次采用ANSI、Unicode、Unicode big endian 和 UTF-8编码方式保存。然后,可以通过"十六进制"的形式观察该文件的内部编码方式、存储有何不同。

1)ANSI:文件的编码就是两个字节"D1 CF",这正是"严"的GB2312编码,这也暗示GB2312是采用大头方式存储的。

2)Unicode:编码是四个字节"FF FE 25 4E",其中"FF FE"表明是小头方式存储,真正的编码是4E25。

3)Unicode big endian:编码是四个字节"FE FF 4E 25",其中"FE FF"表明是大头方式存储。

4)UTF-8:编码是六个字节"EF BB BF E4 B8 A5",前三个字节"EF BB BF"表示这是UTF-8编码,后三个"E4B8A5"就是"严"的具体编码,它的存储顺序与编码顺序是一致的。

5. 总结

在计算机内存中统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8(或其他)编码。

不同的字符集中,字符有不同的字符编码,所以要想判断某个输入的数据是不是某类字符的时候,先确定当前使用的字符集,找到该字符集下该类型字符对应的字符编码范围,即可判断,如判断GB2312下的汉字。

系统只是把这个字符告诉终端,终端去字体中找到这个字符对应的图像,再把这个图像显示出来。如果字体中没有,那就会显示方框等所谓的乱码。

emoji的支持也是一样的,所以实际上是字体的功劳。可能系统在emoji的渲染上支持一些额外的特性(比如颜色,或者干脆用图片来代表emoji字符)。

现代操作系统内部都是用Unicode来处理字符的。设定字符集实际上是告诉系统如何处理外码和内码的对应,比如同一个字符,在UTF-8和UTF-16中的编码可能是不同的,字节数量也可能是不同的,但是对应的unicode其实同一个。比如系统处理一个字符,根据设定的字符集找到对应的UTF-8编码输出给终端,但是终端却是用UTF-16的规则来理解这些编码,那自然就会出错了。

参考文章,感谢:
https://www.cnblogs.com/ooon/p/4818574.html
https://www.cnblogs.com/cthon/p/9297232.html
https://blog.csdn.net/LightUpHeaven/article/details/92001322

举报

相关推荐

0 条评论