理清字符集和字符编码关系

Posted 木可大大

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了理清字符集和字符编码关系相关的知识,希望对你有一定的参考价值。

计算机内部由集成电路(Integrated Circuit,IC)构成,IC的所有引脚,只有直流电压0V和5V两个状态。也就是说,IC的一个引脚,只能表示两个状态。正是由于这个原因,决定了计算机的信息只能用二进制数处理。

由于计算机底层使用二进制数来存储和传输数据,而我们人类使用文字、数字和图形符号来表达信息,因此两者之间需要通过某种映射关系来实现。根据映射方向的不同,又可以分为编码和解码。文字、数字等转换成二进制数被称为编码,而二进制数转化为文字、数字和图形符号等称为解码。其中,文字与符号总称为字符(Character),而字符的集合就是字符集(Charset)。常见的字符集包括ASCII字符集、GB2312字符集(简体字符集)、GBK字符集(简繁字符集)和通用字符集(UCS)和Unicode字符集。ASCII

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)。ASCII字符集包含128个字符,它用8bit表示,其中,第一位用0表示。ASCII编码则是一种将ASCII字符集中的字符映射到二进制数的关系,譬如:A -> 65

 

技术分享图片

GB系列

由于中文常用字达到好几千,因此8bit不够用了,增加到16bit,那么就GB2312编码就可以表示2^16=65536字符。GB2312编码就是将这些字符映射到二进制能表示的数,方便计算机存储或传输。

由于汉字种类繁多,除了6000多种简体字体以外,还有繁体字,针对这种情况,GB2312就不能满足了。此时,我们提出了GBK编码方式。

除了简体字、繁体字之外,由于我们是多民族国家,每个民族可能对应一种字符,那么就需要一种新的编码方式来满足这种需求--GB18030。

Unicode

为了整合全世界的所有语言文字,我们的先辈们想出了一个方法Unicode(Universal Mutiple-Octet Coded Character Set),它只是字符集,却没有规定这个二进制该如何存储、传输。其中,它的字符集称为Universal Character Set (UCS),它规定了需要多少字节存储字字符,分别有2个字节和4个字节,各自对应UCS-2、UCS-4。而UTF(Unicode Transformation Format)规定了字符如何传输和存储。UTF又分为UTF-8、UTF-16和UTF-32。我们重点介绍下UTF-8。

根据Huffman编码的思想(最常出现的字符编码尽量的短),以及不同符号使用不同的字节长度表示,因此UTF-8采用了1-4个字节表示一个符号,这种变长的编码方式。它的编码规则如下:

1.对于单字节的符号,字节的第一位置0,后面7位为这个符号的Unicode码。因此,对于英语字母,UTF-8编码和ASCII码是相同的。

2.对于n个字节的字符(n>1),第一个字节的前n位都置为1,第n+1位置为0,后面字节的前两位一律置为10。剩下的没有提及的二进制位,全部为这个符号的Unicode码。

Unicode 和 UTF-8 之间的转换

这里只介绍Unicode转换为UTF-8 ,以汉字 "柯" 为例。已知 "柯" 的Unicode码是 \u 67ef(0110 0111 1110 1111),根据上表,我们可以知道 "柯"这个Unicode对应的UTF-8编码需要3个字节。然后,从0110 0111 1110 1111从由往左依次取数放入到1110 xxxx 10xx xxxx 10xx xxxx中,得到最终的结果是 1110 0110 1001 1111 1010 1111,转换成十六进制是E6 9F AF。

大端与小端

UTF-16、UTF-32是多字节传输,存在字节序的问题,而UTF-8是单字节传输,则不存在字节序的问题。为了帮助大家理解字节序的问题,我还是举个栗子吧,仍来以汉字 "柯" 为例,它的Unicode码是67ef,它需要两个字节存储,一个字节是67,另一个字节是ef。如果采取大端方式来存储,那么67在前,ef在后,而小端方式刚好相反。

由于UTF-16、UTF-32存在两种存储方式,那么就需要我们标识我们采用了何种存储方式。我们采用在文件开始位置输入特殊字节序列(字节序标记,Byte Order Mark,bom)来标识我们采用了哪种方式,如果文件头两个字节是FF FE(FF比FE大1),则表示采用大端方式;如果文件头两个字节是FE FF,则表示采用小端方式。

 

技术分享图片

欢迎关注微信公众号:木可大大,所有文章都将同步在公众号上。

以上是关于理清字符集和字符编码关系的主要内容,如果未能解决你的问题,请参考以下文章

java中字符的String.length()和字符代码单元的关系

常见编码规范及其应用

GoLang 高性能编程之字符串拼接

字符编码的来源,asciiunicode和utf-8编码的关系

二进制那些事

二进制那些事