文字显示1——字符与编码

字符与编码

对于文字,实际上只是图形符号,每一个字符对应一个符号,英文单词为glyph。对于计算机来说处理图形符号并不容易,但是处理数字却非常简单,因此可以将字符转换成数字,然后直接处理数字就行。例如:可以用数字1代表字符‘a’,当在处理字符时如果遇到数字1就直接在屏幕上绘制一个‘a’图形符号就行。当把一个语言中所有的字符都用一个独一无二的数字表示时,这个过程就是编码。例如在ASCII表中使用数字表示了所有美式英文的符号。

编码类型

对于每种语言来说一般都会有自己的编码表,例如美式英文有ASCII表,简体中文有GBK编码,西欧语言有Latin-1编码,繁体中文有Big5编码。

 

编码大小

对于编码使用的数字到底要用多大的数字呢?数字太大处理字符时会占用太多得内存,数字太小又无法表示所有得字符。对于英文来说字符比较少,一个字节就够,但对于中文来说一个字节肯定不够,至少需要两个字节。

 

ASCII

ASCII表是美国制定,用于美式英语。在以上的ASCII表中,可以看到总共有128个字符,128个字符只需要一个7位的二进制就行,一个子节是8位,所以用一个子节表示就行。

 

ISO-8859

ASCII表主要用于美式英语,对于其他英文不能良好支持,例如英国的英镑符号(£)ASCII表中就没有。为了支持其他的字符就需要对ASCII表进行扩展,一个子节有8位,可以表示256种字符,ASCII表用了128字符,其余128个字符就可以用于扩展。ISO-8859就是将ASCII表进行扩展,以支持其他英文中的字符,或者拉丁文字。前面提到的西欧文字Latin-1编码就是ISO-8859-1,里面包含了“àáèéêìí”等大于128的扩展字符,以支持丹麦语、荷兰语、法罗语、德语等等。ISO-8859中有15个字符集,每个字符集对应了不同的语言,对于每个字符集中的字符都不超过256种,小于128的字符都与ASCII一样,大于等于128的字符都是相应语言的扩展。因为不超过256种字符,所以用一个子节就可以表示了。

 

中文编码

中文种有大量字符,仅用一个子节肯定不足以表示,至少需要两个子节才行。GB2312是由

中国国家标准总局1980年发布的,用于简体中文显示,这里面只包含了简体中文,没有包括繁体。因为台湾,香港使用的是繁体中文,为了支持繁体便有了Big5编码。后来国标为了支持繁体便对GB2312进行了扩展,扩展后称为GBK,GBK同时包含了简体和繁体。虽然GBK和Big5都支持繁体,但是GBK与Big5不兼容,例如十六进制B0A1在GBK中代表字符‘啊’,而在Big5中代表‘陛’。在GBK和GB2312中每个字符占用两个子节。

 

GB2312采用区位码进行的编码,GB2312编码表

GB2312在使用双子节显示前需要对区位码进行转换,转换规则如下:

以“中“字为例子:中字的区位码为5448,54是区码,48是位码,这两个都是十进制。首先需要将区码和位码都转换成16进制,转换后为36和30。然后将两者分别加上A0,得到D6D0,D6D0也就是”中“字的双子节编码。

“中”字转换过程:5448转成16进制3630+A0A0=D6D0

 

GBK是在GB2312双子节编码的基础上在进行的扩展,GBK编码表

GBK编码不需要转换之间就可以显示。

 

Big5编码使用的也是双子节编码无需转换,可直接显示,Big5编码表

 

GB2312编码范围A1A1-FEFE,从范围中可以看出最小字符时A1A1,也就是说GB2312两个字节都大于等于A1,大于128(0x80),而ASCII中所有的字符都小于128,所以GB2312本身兼容ASCII,两者编码没有冲突可以同时用于显示。

GBK编码范围是8140-FEFE,最小字符是8140,两个字节中只有第一个字节一定大于128,第二个字节是可以小于128的。如果ASCII和GBK同时用于显示时,如果一个字节大于128,此时,应该和第二个字节组成一个GBK编码。如果小于128则是ASCII,所以GBK也兼容ASCII。

Big5编码范围和GBK一样是8140-FEFE,但与GBK不兼容,具体可以对照两者的编码表,可以看到同一个编码对应不同的汉字。Big5显示原理和GBK一样,也兼容ASCII。

 

关于输入法的半角和全角

从GB2312和GBK的码表中可以看到有一个区单独用来表示ASCII字符。

中文输入都可以设置输入半角和全角,以下是微软拼音输入法设置截图,

当输入时设置的是半角时对于ASCII中的字符会使用ASCII编码也就是一个字节。如果使用全角输入时会使用GBK/GB2312中的编码,也就是用两个字节。半角全角主要就是影响中文输入时ASCII字符的编码,不会影响其他中文的输入。半角和全角文字对比,图片中为一个半角然后一个全角字符,全角的字符一般会更加宽一些。实际使用时大部分都是使用半角字符,很少使用全角。

 

这里有两个网站可以用于查询汉字编码

https://bianma.supfree.net/chaye.asp?id=4F60

https://www.qqxiuzi.cn/bianma/zifuji.php

 

编码选择

当有一个文本文件时,我们必须知道文件的编码才能正确显示文字。例如以下是对GB2312文字“AaBbCc文本显示测试”用不同编码进行显示:

 

从以上的图片可以看出,除了GB2312显示正常外,其他编码模式下都是乱码,这也是有时文件出现乱码的原因,即编码选择错了。从图片中还可以看到所有编码模式下英文“AaBbCc”都显示正常,因为根据前面的介绍这几种编码都兼容ASCII。目前对于大部分的编码类型都兼容ASCII,所以如果是文本中只包含ASCII,那么文本可以在任何电脑上显示正常。

 

Windows系统选择编码

文本文件必须要知道编码才能显示,Windows系统又是如何知道一个文本的编码呢?在Windows的“控制面板->时间和区域->区域”中可以设置一个默认的编码,如下图:

如果你把编码设置错了,那么有些程序就有可能出现乱码。

 

有些文本编辑提供手动选择文本的编码,比如Notepad++。

 

Unicode统一编码

当文本的编码页选择错误后就会出现文字乱码,不同语言会有不同的编码,语言的总类很多,编码表也会有很多,这也增加了乱码的发生。还有一个更严重的问题如果想要中文(GB2312)和西欧的文字(ISO-8859-1)同时显示,由于两种编码不相容,所以无法做到。为了解决以上问题,便诞生了Unicode编码。Unicode将世界上所有的文字统一同时编码,Unicode编码也就同时包含了所有语言,这样无需选择编码,也可以同时显示多种语言。

 

Unicode需要表示所有语言的字符,到底要使用多少个字节存储呢?Unicode本身并没有规定要用几个字节存储,它只规定了字符的编码,所以Unicode本身是一个可扩展的编码,可以一直添加字符。Unicode把字符分为多个平面,目前规定最多用17个平面。每个平面使用两个字节(16位),因为17个平面需要用5位才能表示,所以目前Unicode至少需要21位才能完全表示。在Unicode中一个平面可以存放65536个字符,对于大多数常用的字符都存放在0平面。Unicode编码表

 

UTF-8

Unicode本身没有规定字符如何存储,UTF-8就是一种用来存储Unicode字符的方案,也是目前使用最广泛的Unicode方案。

 

UTF-8是一种变长字节编码方式,根据字符在Unicode中的编码,使用不同的字节存储,编码越大,字节越多。UTF-8最多可用到6个字节,字节结构如下:

1字节 0xxxxxxx

2字节 110xxxxx 10xxxxxx

3字节 1110xxxx 10xxxxxx 10xxxxxx

4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

其中的‘x’表示Unicode编码的1位。

在Unicode中前128个字符是和ASCII完全一致,前128个字符用7位就可以表示,在UTF-8中也是1个字节,这使得UTF-8完全兼容ASCII。

Unicode同时支持中文简体和繁体,但是与GBK不兼容。

 

对于多个字节,例如‘中’字,Unicode编码位4E2D,二进制‘100 1110 0010 1101’,有15位,所以需要三个字节,UFT-8的二进制为‘11100100 10111000 10101101’,UTF-8十六进制为E4B8AD,中字的UTF-8编码也就是E4B8AD。

 

Unicode也有其他存储方式,UTF-16与UTF-32,其中UTF-16存储字符使用两个或四个字节存储,也就是说即使存储ASCII也使用的是两个字节,这使得UTF-16与ASCII编码不兼容。UTF-32使用4个字节表示一个字符。

 

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值