计算机中的字符编码

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

1. ASCII 编码

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

部分ASCII码对应值

英语128个符号编码已足够,但是显示不同国家的语言时,128个符号是不够的。于是有的国家开始利用ASCII编码里的高位,0—127表示的符号是一样的,不同国家在128—255这一段所表示的字符却不同。在字符比较多的国家,255个字符也是不够的,因此仍采用1个字节的编码受到限制。
其它国家为了显示本国的语言,都对ASCII码进行了扩展,加入了本国的语言编码,这种编码方式为ANSI编码,用2个字节来表示,ANSI编码跟操作系统有直接关系,你安装什么操作系统,那你的ANSI编码就是相应的编码。例如:我们安装的是中文操作系统,对应的默认编码GB2312。

  • GB2312编码:简体中文、全角字符编码,理论上最多表示65536个汉字;
  • GBK编码:对GB2312进行了扩展,用于显示罕见汉字;
  • BIG5编码:繁体汉字编码;
  • JIS编码:日本文字编码。

2. Unicode

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

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

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

Unicode编码的符号集只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。比如汉字"跳"的unicode是十六进制数8DF3,转换成二进制数足足有15位(1000110111110011),也就是说这个符号的表示至少需要2个字节。也会有序号更大的符号,可能需要3、4个字节,甚至更多。
那么,如何才能区别Unicode和ASCII?Unicode编码怎么在计算机内存储呢?若每个符号都占用四个字节编码表示,那么每个英文字母前三个字节是0,极大的浪费存储空间,原英文文本文件的大小会因此大出三倍,显然无法接受。

3. UTF-8

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

UTF-8的编码规则:

  1. 对于单字节的字符,字节的第一位设为0,后面7位为这个符号的Unicode,因此对于英语字符,UTF-8和ASCII码相同;
  2. 对于n字节的字符(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

Unicode符号范围 | UTF-8编码方式
(十六进制)|(二进制)
--------------------+---------------------------------------------
0000 0000 — 0000 007F | 0xxxxxxx
0000 0080 — 0000 07FF | 110xxxxx 10xxxxxx
0000 0800 — 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000 — 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

已知"跳"的Unicode是4DF3(1000110111110011),根据其值位于的范围可知,"跳"的UTF-8编码是"11101000 10110111 10110011",转换成十六进制就是E8B7B3。

也就是说,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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352