计算机字符编码详解与汇总

前言

       计算机中的数据是以二进制格式表示的(其中8位二进制称为一个字节,比如00100101就是一个字节。通常为了更方便的表示二进制数据,也可以转换成16进制表示出来,比如00100101就可以用0x25来表示)。把所有字符转换成二进制数据的规则就是字符编码。字符编码的方式很多,本文对每一种字符编码做尽可能详细的讲解。

       本文中红色字体或加粗字体是需要重点理解或者记忆的。

1. ASCII

       ASCII是美国国家标准定制的一套基于拉丁字母的电脑编码系统,可表示数字、字母等字符符号。

       一个ASCII码在计算机中由一个字节存储,因此它最多可表示256个符号(一个字节为8位,2的8次方等于256),实事上,标准的ASCII编码时只用到了低7位(最高位统一为0,或者为奇偶校验位),故ASCII码可表示的数据一共只有128个(2的7次方)。这128个字符中,其中95个为可显示字符(可打印字符,比如数字、字母、标点符号),还有33个如比如“换行”之类的控制字符(控制字符主要是用来操控已经处理过的文字)。

       对于ASCII具体哪个编码表示哪个符号,大家可以去查阅ASCII编码码表,并具最好能记住数字符、字母、回车换行等常用字符对应的ASCII编码,至少记住它的十进制编码。

常用字符对应的ASCII编码:

回车,ASCII码13(十进制,下同)
换行,ASCII码10
空格,ASCII码32

数字0到9,ASCII依次是48到57

大写字母A到Z,ASCII依次是65到90

小写字母a到z,ASCII依次是97到122

大小规则总结:

1)数字0~9比字母要小。如"7"<"F";

2)数字0比数字9要小,并按0到9顺序递增。如"3"<"8"

3)字母A比字母Z要小,并按A到Z顺序递增。如"A"<"Z"

4)同个字母的大写字母比小写字母要小。如"A"<"a"。

 

2. iso8859-1

       iso8859-1通常叫做Latin-1,它和ascii编码相似,都属于单字节编码,不同于ASCII的是,每个字节中的最高位也参与了编码(如果最高位为0,它的意义同ASCII)。正因为如此,iso8859-1最多能表示的字符范围是0-255,应用于英文系列。很明显,iso8859-1编码表示的字符范围很窄,无法编码中文字符。尽管如此,我们可以先把中文字符按照其它的编码方式编码成二进制数据,然后将编码后的结果再逐字节逐字节的用iso8859-1解码。也就是说,中文字符,它没有iso8859-1编码,但可以在用其它编码方式编码后的基础上再用iso8859-1编码来表示。举个栗子,虽然“中文”的“中”这个字不存在iso8859-1编码,可以先把它按gb2312编码方式编码为"d6d0"这个二字节的编码(16进制),然后将它拆开为两个字节("d6" 与 "d0"),每个字节都可以看作是一个iso8859-1码。

iso8859-1编码在网络传输中的利用:

       iso8859-1由于是单字节编码,和计算机最基础的表示单位一致,因此在很多网络传输协议上,默认使用iso8859-1编码。网络上传输的数据都是二进制的,服务器从网络io流中收到这些数据后,默认把每个字节的数据按iso8859-1编码来处理。

       实事上,通过网络流传输中文时,客户端可以先把中文字符按照其它的编码方式(比如GBK或UTF-8)转换成字节数据发送到服务器,服务器收到后在不指定编码方式的情况下默认会逐个逐个字节的按照iso8859-1编码方式来解码。

       写点题外话,对于java web程序员来说,有时候可以在servlet代码中看到类似于String str = new String(restr.getBytes("iso8859-1"),"utf-8");的转换代码,它的意思就是先把字符串restr通过restr.getBytes("iso8859-1")编码为字节数组(restr是请求参数被按照iso8859-1方式解码后的结果。如果请求参数为中文,因为iso8859-1编码无法直接解码中文,会导致解码后的restr为乱码),然后再按照utf-8的编码方式重新转换为一个新的字符串。

       当然,在java web中也可以用request.setCharacterEncoding("utf-8");方法,直接告诉服务器按照指定的utf-8方式编码。但值得一提的是在执行setCharacterEncoding()之前,不能执行任何getParameter(),而且,该指定只对POST方法有效,对GET方法无效。原因是在执行第一个getParameter()的时候,java将会按照编码分析所有的提交内容,而后续的getParameter()不再进行分析,所以setCharacterEncoding()无效。而对于GET方法提交表单是,提交的内容在URL中,一开始就已经按照编码分析所有的提交内容,setCharacterEncoding()自然就无效。多说一句,为了避免总是要写setCharacterEncoding("utf-8"),通常会在web.xml配置文件中配置一个最上层的字符编码过滤器。

 

3. GB2312

       无论是ascii码还是iso8859-1码,都无法直接编码中文,于是有了GB2312码。GB2312 是对 ASCII 的中文扩展,考虑到每个ASCII码只用了一个字节的底7位(高位为0),所以每个的ASCII码都小于或等于127(01111111)。于是规定:一个小于127的字符的意义与原来相同(为了兼容ASCII码),但两个大于127的字符连在一起时,就表示一个汉字,而且这两个字节中,前面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们可以组合出大约7000多个简体汉字,这就是GB2312编码。

       这样,计算机在解码时,可以逐字节逐字节的判断它的是否小于127,如果小于或等于127,就按ASCII直接解码,如果大于127,就再往后多读取一个字节,如果后面那个字节也大于127,就把这两个字节连起来再通过查找GB2312编码码表来解码成一个中文字符。由此可见,GB2312码是一种变长的编码方式,英文占一个字节(而且小于127),中文占两个字节(都是大于127的字节),而且兼容ASCII码。

4. GBK

       GB2312码中用两个连续的大于127字节的数据来表示一个中文,它能表示的数量刚好也就满足简体中文编码的需要。后来发现,其实表示一个中文的两个字符中,可以不要求两个字节都大于127,只要第一个字符大于127,就可以作为解码中文的开始字符,第二个字符是否大于127都不会对计算机解码造成二义性错误(在逐字节解码的过程中,只要读到一个节字大于127,就直接往后再读一个字节,不判断第二个字节是否大于127就直接将这两个字节连到一起然后再通过编码码表来解码)。这样,在GB2312码的基础上,通过不限定第二个字节是否大于127的方式扩展出了GBK码。GBK包括了GB2312的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。

5. GB18030

       在GBK码的基础上,再进一步扩展,增加了一些连续四个字节的汉字,于是也就有了GB18030码,GB18030码完全兼容GBK码,而且增加了少数民族文字。

综上所述,以上能表示中文的字符编码中,可编码的范围从小到大依次是:ASCII < GB2312 < GBK < GB18030,而且它们后者兼容前者,其中GB2312和GBK用两个字节表示中文,GB18030有些用两个字节表示一个汉字,有些有两个字节表示汉字。

6.UNICODE编码

       因为每个国家都搞出像天朝这样一套自己的编码标准,在跨国跨语言使用时存在储多不便。为了统一,ISO(国际标谁化组织)重新搞了一套标准,也就是UNICODE编码。

       UNICODE这是最统一的定长编码,有双字节编码(UCS-2)和四字节编码(UCS-4,备用)两种。其中UCS-2包括英文字母在内,只能表示65535个字符,IOS预备的UCS-4方案,可以组合出21亿个不同的字符出来(最高位有其他用途)。

       其实,英文字母只用一个字节表示就够了,但是其他更大的符号可能需要3个字节或者4个字节,甚至更多。而Unicode统一规定,每个符号用两个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说其实是极大的浪费。

       而且它不兼容iso8859-1编码,也不兼容gb2312、gbk、gb18030等任何编码。不过,相对于iso8859-1编码来说,uniocode编码只是在前面增加了一个0字节,比如字母a为"00 61"。

       但是UNICODE这种定长编码便于计算机处理(注意GB2312/GBK不是定长编码),而unicode又可以用来表示所有字符,所以在很多软件内部是使用unicode编码来处理的,比如java。

       需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。于是出现了多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示unicode。unicode在很长一段时间内无法推广,直到互联网的出现。
7.UTF

       考虑到unicode编码不兼容iso8859-1编码,而且容易占用更多的空间:因为对于英文字母,unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码,utf编码兼容iso8859-1编码,同时也可以用来表示所有语言的字符,不过,utf编码是不定长编码,每一个字符的长度从1-6个字节不等。另外,utf编码自带简单的校验功能。

       UTF-8是Unicode的实现方式之一,一般来讲,对于UTF-8,英文字母都是用一个字节表示,而汉字使用三个字节。另外,还有UTF-16(字符用两个字节或四个字节表示),UTF-32(字符用四个字节表示)。

       顾名思义,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。UTF-8就是在互联网上使用最广的一种unicode的实现方式,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。
  UTF-8的编码规则很简单,只有二条:
    (1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
    (2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

       综上所述,UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。而且UTF-8编码的文件比GB2312更占空间大。

   以上就是本人以常见字符编码的汇总,正文中本文中红色字体或加粗字体是需要重点理解或者记忆的。想了解更多信息,请关注本人公众号

时间: 2024-10-30 10:50:21

计算机字符编码详解与汇总的相关文章

字符编码详解——彻底理解掌握编码知识,“乱码”不复存在

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://polaris.blog.51cto.com/1146394/377468  每一个程序员都不可避免的遇到字符编码的问题,特别是做Web开发的程序员,"乱码问题"一直是让人头疼的问题,也许您已经很少遇到"乱码"问题,然而,对解决乱码的方法的内在原理,您是否明白?本人作为一个程序员,在字符编码方面同样遇到不少问题,而且一直对各种编码懵懵懂懂.不清不楚:

java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**

一.基础知识 在了解各种字符集之前我们需要了解一些最基础的知识,如:编码.字符.字符集.字符编码基础知识. 编码 计算机中存储的信息都是用二进制表示的,我们在屏幕上所看到文字.图片等都是通过二进制转换的结果.编码是信息从一种形式或格式转换为另一种形式的过程,通俗点讲就是就是将我们看到的文字.图片等信息按照某种规则存储在计算机中,例如'c'在计算机中怎么表达,'陈'在计算机中怎么表达,这个过程就称之为编码.解码是编码的逆过程,它是将存储在计算机的二进制转换为我们可以看到的文字.图片等信息,它体现的

JavaScript Unicode 字符编码详解教程

Unicode 是为了解决传统的字符编码方案的局限而产生的,例如ISO 8859所定义的字符虽然在不同的国家中广泛地使用,可是在不同国家间却经常出现不兼容的情况.很多传统的编码方式都有一个共同的问题,即容许电脑处理双语环境(通常使用拉丁字母以及其本地语言),但却无法同时支持多语言环境(指可同时处理多种语言混合的情况). 一.Unicode是什么? Unicode源于一个很简单的想法:将全世界所有的字符包含在一个集合里,计算机只要支持这一个字符集,就能显示所有的字符,再也不会有乱码了. 它从0开始

关于计算机字符编码的问题!

问题描述 关于计算机字符编码的问题! 计算机字符编码一直困扰我,真希望有大牛帮我解惑: 1. 输入法在输入文本的时候其实是输入对应字符编码集的对应字符的二进制编码,那么这时如果要保存,只需要保存这些二进制字节就可以了,读的时候用输入时使用的编码集解码即可,为什么还有选择保存字符编码这一项,以上只是我的理解.比如: 在windows中使用记事本时,我们输入:你好,世界! 这时我们使用的是输入法在当前环境中默认的字符编码方式进行输入的,那么我们 需要直接保存即可,但保存时有额外选项,即选择编码方式的

收藏:ASP的函数详解大汇总

函数|详解 ASP的函数详解 join(expression,"连接符") split :接收相关的参数,使之成为数组. Array() FUNCTION: 返回一个数组 SYNTAX: Array(list) ARGUMENTS: 字符,数字均可 EXAMPLE: RESULT: 建立了一个包含7个元素的数组myArray myArray("Sunday","Monday", ... ... "Saturday") CInt

PHP中ASCII码对照表与字符转换详解

通用的ASCII码对照表 图解ASCII码对照表图,以字符A为例 Dec表示十进制,如65 Hx表示十六进制,如41 Oct表示八进制,如101 Char表示显示字符,如A ASCII码对照表图分为两个单元 1,控制字符 0-31和127 2,可显示字符 32-126 (1)48-57为0到9十个阿拉伯数字: (2)65-90为26个大写英文字母: (3)97-122号为26个小写英文字母: (4)其它标点符号.运算符号等: 二,ASCII扩展码对照表   三,PHP字符转换函数说明 具体字符转

Java 和 JavaScript 真正通用的Base64编码详解_java

 Java 和 JavaScript Base64编码 在开发Java  Web应用的时候,可能会在服务器端用Java做Base64编码,而在客户端用JavaScript进行解码.这样就要求两边的Base64编码机制保持一致. 使用Base64编码,可能会碰到各种奇怪情况,甚至怀疑编码有bug.但实际上不是这样的.Base64理论上操作的对象不是字符串而是字节数组.它的原理就是把ASCII码的255个字符缩小到用64个来表示.具体就是原来三个字节用四个字节表示,编码后长度有一定的增长. 1) 最

ASP Replace 字符替换详解

title=replace(title,"DF","SD",1,-1,1) replace函数参数详解: 参数1:源字符串 参数2:要被替换的字符 参数3:新的字符 参数4:值为1,指定从第一个字符开始搜索该字符串 参数5:值为-1 指定每一个子串都要被替换 参数6:值为1 指定字符串的比较不区分大小写. vbscript中replace()详细说明: 功能:在字符串中查找,替代指定的字符串. 格式:replace(strtobesearched,strsearch

常用字符集编码详解(ASCII GB2312 GBK GB18030 unicode UTF-8)_应用技巧

ASCII ASCII码是7位编码,编码范围是0x00-0x7F.ASCII字符集包括英文字母.阿拉伯数字和标点符号等字符.其中0x00-0x20和0x7F共33个控制字符. 只支持ASCII码的系统会忽略每个字节的最高位,只认为低7位是有效位.HZ字符编码就是早期为了在只支持7位ASCII系统中传输中文而设计的编码.早期很多邮件系统也只支持ASCII编码,为了传输中文邮件必须使用BASE64或者其他编码方式. GB2312 GB2312是基于区位码设计的,区位码把编码表分为94个区,每个区对应