浅谈字符编码

来源:互联网 发布:淘宝好鞋店推荐知乎 编辑:程序博客网 时间:2024/05/16 10:47

   当你想到文本的时候,你大概那会认为那仅仅是在计算机屏幕上显示出来的字符。但是计算机不能直接处理我们认识的字符,它处理的只能是位和字节。任何一段你在屏幕上看到的文本,实质上都是以某种编码形式存在的。字符的编码方式有很多,一些编码方式特别为某些特定的语言设置,还有一些则可以用来编码多种语言。粗略的讲,字符的编码提供了一种人类所认识的字符到存在于计算机上数字的映射。

     当我们打开记事本,随便输入一些文字,然后保存的时候,出现的保存界面有如下选项:

        

在编码一栏里我们可以选择ANSI、Unicode、Unicode big endian、UTF-8,保存文件时默认的编码方式是ANSI。

下面对这几个编码方式进行一些说明。

    一、ANSI

    要说这个,就不得不先提提ASCII(American Standard Code for Information Interchange)码。最开始在英语国家,英文的一个字符用一个字节表示,实际上只用了一个字节的后7位。这样就可以表示出128个字符,其中包括不能打印出来的控制符号。后来那多出来的一位被许多的设备厂商占为己用(用来表示一些自己规定的特殊符号),于是原本和谐的局面被打破了,各设备不能相互正常的通信了。再后来,ANSI(美国国家标准协会)就站出来将多出128的一些字符编码进行了明确的规定。于是就有了这样一种新的编码方式。

    在windows简体中文版中,ANSI的具体编码规则是这样的,对于英文文字是ASCII编码,对于中文是GB2312。

    二、Unicode

    英文字符集能编码了,那中文怎办呢。你可能要说上面不是有个GB2312吗,GB2312的全称是中华人民共和国国家汉字信息交换用编码,这是和ASCII码不兼容的另一种编码集。要是有一种能包容这个星球上所有文字的字符集那该有多好,于是Unicode的字符编码集诞生了,很重要的一点就是,Unicode和ASCII兼容。这里要特别注意的一点是,这里说的Unicode只是一个字符集,至于具体到一个字符应该怎样存储和传输,那又是另一个问题了,我们称之为实现方式。Unicode的实现方式有很多种,上图记事本中的“Unicode”就是其中一种,称为“UTF-16”或者“UCS-2”。UTF,是Unicode Transformation Format的缩写形式。根据英文全称翻译就是Unicode传输格式,这样它的意义就更加明确了。在这种实现方式中,一个字符用2个字节也就是16位来编码,上面名称中数字的意义也明确了吧。其实这是一种很自然的逻辑,既然一个字节不能表示所有的文字,那么就用两个字节来表示。但是两个字节应该怎样来排列呢,哪个在前面?这还不简单,在文件开头说明一下不就完了。因此“UTF-16”编码的文件,前面会多出称为“Unicode Byte Order Mark”(unicode字节顺序标志)的两个字节,FF和FE。如果FF在前就是small endian(小端模式),其实上图中的“unicode”就是小端模式,后面一项就是big endian(大端)了。 两个字节进行编码好像挺好的,但是使用英文的人们就不怎么爽了。我没有用到另外一个字节,文件大小却平白无故增大了一倍。针对“utf-16”的不足,于是人们研究出了另一种unicode实现方式,那就是“UTF-8”了。

    三、UTF-8

    再次强调,UTF-8只是unicode的实现方式之一。UTF-8是一种可变长的编码方式。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

--------------------------------------------------------------------------------------------------

    下面,以汉字“涛”为例,演示如何实现UTF-8编码。
已知“涛”的unicode是6D9B(110 1101 1001 1011),根据上表,可以发现6D9B处在第三行的范围内(0000 0800-0000 FFFF),因此“涛”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“涛”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“涛”的UTF-8编码是“11100110 10110110 10011011”,转换成十六进制就是E6B69B。E6B69B就是“涛”的UTF-8编码。

原创粉丝点击