字符编码介绍

前言
通过本文你能了解以下内容:

  • 字符编码是什么,起什么作用?
  • 字符编码的发展过程。
  • 常见字符编码ASCII、Unicode、UTF-8作用与区别。
  • 异常乱码的原因。

我们知道,计算机的世界里只有0和1,一切的文件、音乐、图片、视频等等都是由0和1的数据组成。那我们日常使用的输入法打出的文字,符号是如何被计算机识别的呢?复杂的世界语言、符号计算机又是如何管理区分的呢?这些问题将通过本文进行探讨。

一、什么是字符编码?

字符编码是将字符映射成其他形式的数据编译在计算机中存储和传输的映射规则。
以较为熟悉的数字来说:

十进制二进制十六进制
1010100x0A
660100 00100x42

这样我们熟悉的十进制数就转为了计算机熟悉的0/1。
类似的,字符也可以进行特殊的编码,转为为计算机能够熟悉的数据,以大名鼎鼎的ASCII编码为例:

二进制十进制十六进制缩写含义/作用
0000 000000x00NULL空字符(Null)
0000 000110x01SOH标题开始
0000 001020x02STX文本开始
0000 001130x03ETX文本结束
0000 010040x04EOT传输结束
0000 010150x05ENQ请求
0000 011060x06ACK确认回应
0000 011170x07BEL响铃
0000 100080x08BS退格
0000 100190x09HT水平定位符号
0000 1010100x0ALF换行键
0000 1011110x0BVT垂直定位符号
0000 1100120x0CFF换页键
0000 1101130x0DCRCR(字符)
0000 1110140x0ESO取消变换(Shift out)
0000 1111150x0FSI启用变换(Shift in)
0001 0000160x10DEL跳出数据通讯
0001 0001170x11DC1设备控制一 (XON激活软件速度控制)
0001 0010180x12DC2设备控制二
0001 0011290x13DC3设备控制三 (XOFF停用软件速度控制)
0001 0100200x14DC4设备控制四
0001 0101210x15NAK确认失败回应
0001 0110220x16SYN同步暂停
0001 0111230x17ETB区块传输结束
0001 1000240x18CAN取消
0001 1001250x19EM连线介质中断
0001 1010260x1ASUB替换
0001 1011270x1BESC退出键
0001 1100280x1CFS文件分隔符
0001 1101290x1DGS组群分隔符
0001 1110300x1ERS记录分隔符
0001 1111310x1FUS单元分割符
0111 11111270x7FDELDelete字符
二进制十进制十六进制字符
0010 0000320x20(space)
0010 0001330x21!
0010 0010340x22"
0010 0011350x23#
0010 0100360x24$
0010 0101370x25%
0010 0110380x26&
0010 0111390x27
0010 1000400x28(
0010 1001410x29)
0010 1010420x2A*
0010 1011430x2B+
0010 1100440x2C,
0010 1101450x2D-
0010 1110460x2E.
0010 1111470x2F/
0011 0000480x300
0011 0001490x311
0011 0010500x322
0011 0011510x333
0011 0100520x344
0011 0101530x355
0011 0110540x366
0011 0111550x377
0011 1000560x388
0011 1001570x399
0011 1010580x3A:
0011 1011590x3B;
0011 1100600x3C<
0011 1101610x3D=
0011 1110620x3E>
0011 1111630x3F?
0100 0000640x40@
0100 0001650x41A
0100 0010660x42B
0100 0011670x43C
0100 0100680x44D
0100 0101690x45E
0100 0110700x46F
0100 0111710x47G
0100 1000720x48H
0100 1001730x49I
0100 1010740x4AJ
0100 1011750x4BK
0100 1100760x4CL
0100 1101770x4DM
0100 1110780x4EN
0100 1111790x4FO
0101 0000800x50P
0101 0001810x51Q
0101 0010820x52R
0101 0011830x53S
0101 0100840x54T
0101 0101850x55U
0101 0110860x56V
0101 0111870x57W
0101 1000880x58X
0101 1001890x59Y
0101 1010900x5AZ
0101 1011910x5B[
0101 1100920x5C|
0101 1101930x5D]
0101 1110940x5E^
0101 1111950x5F_
0110 0000960x60`
0110 0001970x61a
0110 0010980x62b
0110 0011990x63c
0110 01001000x64d
0110 01011010x65e
0110 01101020x66f
0110 01111030x67g
0110 10001040x68h
0110 10011050x69i
0110 10101060x6Aj
0110 10111070x6Bk
0110 11001080x6Cl
0110 11011090x6Dm
0110 11101100x6En
0110 11111110x6Fo
0111 00001120x70p
0111 00011130x71q
0111 00101140x72r
0111 00111150x73s
0111 01001160x74t
0111 01011170x75u
0111 01101180x76v
0111 01111190x77w
0111 10001200x78x
0111 10011210x79y
0111 10101220x7Az
0111 10111230x7B{
0111 11001240x7C|
0111 11011250x7D}
0111 11101260x7E~

从上面可以发现,ASCII表共128个元素,分为了两部分(33 + 95):

  • 0x00~0x31 + 0x127:用来操控已处理的文字控制符,共33个,多数已弃用。
  • 0x32~0x126:可显示字符,共95个,包含数字、26个大小写英文字母,常见英文标点符号。

通过ASCII能够将常用的英文字母和符号在计算机中进行表示,但中文、日文、韩文等其他文字和符号如何能让计算机识别并显示呢?

二、字符编码的发展

2.1 ASCII的诞生

1837以前文字信息通常以书面的方式进行传递,而这之后进入现代信息时代,摩斯电报的发明将文字信息转为电子信息来传递,在影视作品中经常可以见到通讯士兵使用通讯设备滴答滴答的发送情报,而这正是使用的摩斯电报。摩斯代码的数字化并不是指转为为0/1,而是基于电流的开/关两种状态。基于“开”的时长,长“开”用"-"表示,短“开”用“.”表示,每个字母用1 ~ 4个“-”和“.”表示,后经过改良形成不同版本的摩斯代码:
摩斯代码
再到后来,计算机的发明使用,急需字符的编码,方便人机的交互。
初代计算机的数据识别是通过纸带打孔的方式,纸带固定位置的孔位是否打孔被计算机处理为它能够识别和处理的0或1。
打孔纸带

此时的人机交互繁琐困难,初代程序员面向打孔纸带编程,使用机器语言与计算机进行交互十分繁琐,低效,耗资源,易错。为了使这个过程变得高效,更符合人类交互特点,于是将字符进行编码,计算机对编码的字符进行解码成自己能够理解的0/1编码。
于是ASCII(American Standard Code for Information Interchange美国信息交换标注代码)与1967年由美国制定了,是基于拉丁字母的编码系统,主要用于显示现代英语和其他西欧语言。所占字节为8bit,最早仅上述128个字符,后经过不断迭代扩展,后128个也被定义为其他字图案,例如:

二进制十进制十六进制字符
1110 00112270xE3π
1110 11002360xEC

前128为ASCII码被称为基础ASCII码或标准ASCII码,后128个称为扩展ASCII码。

2.2 字符编码百花齐放和统一

前面提到ASCII编码主要适用英语和西欧语言,但对于其他语言却不适用,例如中文、日语、韩语、泰语、阿拉伯语等等,并且ASCII码仅8位,最多表示256字符,而中文大约共有10万多种字,需要更大容量、更灵活的编码方式,于是不同国家语系对自己的语言文字制定编码规则,例如GBK和GB2312(中国)、EUC-JP(日本)等等。

2.3 GB2312

这里以GB2312为例进行简单介绍:
1980年我国推出GB2312,向上兼容了ASCII。GB2312采用双字节编码,字符编码占16bit。编码范围A1A1 ~ 0xFEFE,其中汉字编码范围0xB0A1 ~ 0xF7FE,共收录6763个汉字,虽然没有收录全部汉字,但基本满足日常生活、生产场景需要,同时GB2312还收录了包括拉丁字母、希腊字母、日文平/片假名字母,俄语西里尔字母在内的682个全角字符。
GB2312编码对所收录的字符进行了分区处理,共94个区(GB2312字符表),例如:

第16区0123456789AB
B0A0
B0B0

"啊"字的GB2312编码就是0xB0A1。

这样不同国家的编码系统满足的自己国家文字编辑的需求,并且向下兼容ASCII,但问题却又出现了。试想这样的场景:
你的阿拉伯朋友给你发了一封邮件,由于邮件内容采用阿拉伯字符编码,你收到邮件后GB2312由于没有收录阿拉伯语字符,导致不能解码出预期字符的问题,从而极易导致文字乱码的现象,这就是由于字符编码和解码出现了混乱。
为了避免这跨编码导致的乱码尴尬,于是Unicode闪亮登场。

2.4 Unicode

国际标准组织1991年制作统一的标准字符集Unicode,又称统一码,万国码。它为每种语言的每个字符设定了统一并且唯一的二进制编码,以满足跨语言,跨平台的文本转换、处理要求。
Unicode编码范围为0x0000000 ~ 0x010FFFF,最多可以容纳17*2^16=1114112个码位。使用17个平面,每个平面有2 ^16=65536个码位。
基本多文种平面
例如“汉字”的Unicode编码为:U+6C49、U+5B57
(Unicode编码查询)

2.5 UTF-8

Unicode虽然解决了跨语言字符处理的问题,但也带来新的问题:

  • 字符’a’在ASCII编码方式下编码为:0x61, 占1字节;字符’a’在Unicode编码方式下编码为:0x00000061,占4字节,这使得一本英文书以两种字符编码方式存储,文件大小差别巨大。

也就是说,虽然Unicode容量大,字符全,但编码占用空间大,使用效率低,基于节约原则,1992年便对Unicode进行了改良,诞生了UTF-8(8位元,Universal Character Set/Unicode Transformation Format)可变长度字符编码,将Unicode字符根据编码数字大小分为1~4字节,常用的英语2字节,汉字3字节,生僻字符4字节等,例如:
UTF-8编码查询

字符ASCIIUnicodeUTF-8
A0100 00010000 0000 0000 0000 0000 0000 0100 00010100 0001
0000 0000 0000 0000 0100 1110 0010 11011110 0100 1011 1000 1010 1101

注:这里的Unicode是指Unicode-32,后续版本中对编码长度进度了改良。
由此可以看出UTF-8节省了字符存储空间,尤其是对于英文字母。
除了常见的UTF-8编码,还有UTF-16可变长字符编码、UTF-32固定长度字符编码。

三、总结

上文从字符编码发展历程的角度介绍了几种常见的字符编码的作用及其优缺点,已经乱码产生的背景和原因,通过字符编码使得全世界范围内的文字、符号得到表达和记录,还包括扩展的图案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值