字符编码详解及由来(UNICODE,UTF-8,GBK)[转帖]

老老很久以前,有相同浩大人数,他们操纵用8个好开合的结晶管来构成成不同的状态,以表示世界上之万物。他们当8独开关状态作为原子单位特别好,于是他们把当下叫做”字节约”。

深信不疑許多人對字符編碼都未是充分了解,透過下文可以清晰的喻各种字符编码方式详解及由来。

再次后来,他们还要举行了部分得以处理这些字节的机器,机器开动了,可以为此字节来整合出双重多之状态,状态开始变来变去。他们见到这样是好之,于是她就立即机器称为”计算机”。

   
一直本着字符的各种编码方式懵懵懂懂,什么ANSI、UNICODE、UTF-8、GB2312、GBK、DBCS、UCS……是未是圈之很晕,假如你细的看本文乃必可以清楚的喻他们。Let’s
go!

千帆竞发计算机只在美国因而。八位之字节一共可以组合出256(2底8次方)种不同之状态。

http://www.phpweblog.net/fuyongjie/archive/2009/03/11/6374.html

她俩拿中的数码从0开始的32栽状态分别规定了奇之用处,一而极设备或者打印机遇上这些约定好的字节时,就如开一些预约的动作。遇上
00×10, 终端就换行,遇上0x07, 终端就于众人嘟嘟叫,例好遇上0x1b,
打印机就打印反白的许,对于极端就就此彩色显示字母。他们看这般充分好,于是就把这些0x20(十进制32)以下的字节状态称为”控制码”。

          
    长期很久以前,有相同浩大人,他们控制就此8只可开合的结晶管来组成成不同之状态,以象征世界上的万物。他们观看8只开关状态是好的,于是他们管立即叫做”字节约”。

她俩同时拿具有的空格、标点符号、数字、大小写字母分别用连的字节状态表示,一直编到了第127声泪俱下,这样计算机就可就此不同字节来存储英语的
文字了。大家看来这样,都感觉到甚好,于是大家还管这个方案叫做 ANSI
的”Ascii”编码(American Standard Code for Information
Interchange,美国音相互换标准代码)。当时世界上富有的计算机都因此相同的ASCII方案来保存英文字。

   
再后来,他们同时开了有足以处理这些字节的机器,机器开动了,可以用字节来整合出广大态,状态开始变来变去。他们看如此是好之,于是她就立即机器称为”计算机”。
   
开始计算机只当美国用。八各类之字节一共可以整合出256(2的8次方)种不同的状态。
   
他们将里面的号子从0开始的32种植状态分别规定了奇特之用,一不过终端、打印机遇上预定好之这些字节被染过来时,就设开一些预约的动作。遇上00×10,
终端就换行,遇上0x07, 终端就向人们嘟嘟叫,例如遇上0x1b,
打印机就打印反白的字,或者极端就因故彩色显示字母。他们视这样不行好,于是就将这些0x20之下的字节状态叫做”控制码”。
   
他们又管具有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第127声泪俱下,这样计算机就足以为此不同字节来存储英语的契了。大家看来这样,都深感蛮好,于是大家都将此方案叫做
ANSI 的”Ascii”编码(American Standard Code for Information
Interchange,美国音交互换标准代码)。当时世界上拥有的微机都因此同一的ASCII方案来保存英文字。
         
   
后来,就像打巴比伦塔一律,世界各地的且起利用计算机,但是洋洋国家为此之不是英文,他们之字母里发生很多是ASCII里没有底,为了好于电脑保存他们的仿,他们操纵以127如泣如诉后的空位来代表这些新的字母、符号,还投入了众多打表格时索要用生及的横线、竖线、交叉等形象,一直把序号编到了最后一个状态255。从128暨255眼看无异于页的字符集被称”扩展字符集”。从此之后,贪婪之人类还无新的状态可以据此了,美帝国主义可能没想到还有第三世界国家之人们也想可以用到电脑吧!

新兴,就像盖巴比伦塔平等,世界各地的还从头采取计算机,但是多国之所以之免是英文,他们为此到之许多字母在ASCII中从来没,为了为得以于电脑中保存他们的文,他们说了算用127如泣如诉以后的空位来表示这些新的字母、符号,还进入了许多写表格时需要因此生至之横线、竖线、交叉等相,一直拿序号编到了最终一个态255。从128顶255当下无异页的字符集被如”扩展字符集”。从此以后,贪婪的人类还没有初的状态可以为此了,美帝国主义可能没想到还有第三世界国家的众人也可望得以为此到计算机吧!

   
等中国人们获取计算机时,已经没得以使用的字节状态来代表汉字,况且有6000大抵独常因此汉字需要保留也。但是及时难休倒智慧的华夏人民,我们不客气地将那些127哀号之后的奇异符号们直接取消掉,
   
规定:一个仅次于127之字符的意思及原来平,但零星个盖127的字符连在一起时,就表示一个中国字,前面的一个字节(他号称高字节)从0xA1之所以到
0xF7,后面一个字节(低字节)从0xA1至0xFE,这样咱们虽可以组合有大约7000大抵单简体汉字了。在这些编码里,我们尚将数学符号、罗马希腊之字母、日文的假名们都编上了,连在
ASCII
里当就是有些数字、标点、字母都备重新编了个别独字节长的编码,这就是经常说的”全角”字符,而本在127哀号以下的那些即使被”半斗”字符了。
      中国全民看看这么很不错,于是便管这种汉字方案叫做 “GB2312″。GB2312
是指向 ASCII 的中文扩展。
     
但是中国底汉字太多矣,我们很快就不怕发现出好多丁之全名没有艺术于此打出来,特别是少数老会烦人家的国领导人。于是我们不得不继续把
GB2312 没有动用的码位找出来老实不虚心地用上。
     
后来还是不够用,于是干脆不再要求低字节一定是127哀号过后的内码,只要第一独字节是过127不怕固定表示即是一个中国字之开头,不管后面和的凡勿是扩张字符集里之情节。结果扩展之后的编码方案被称为
GBK 标准,GBK 包括了 GB2312
的备内容,同时又加了邻近20000只新的方块字(包括繁体字)和标志。
     
后来少数民族也如用微机了,于是我们再次扩展,又加了几千个新的少数民族的字,GBK
扩成了GB18030。从此后,中华民族之知识就可以于微机时代中承受了。
      中国底程序员们顾就同文山会海汉字编码的正经是好之,于是通称他们叫做
“DBCS”(Double Byte Charecter Set
双字节字符集)。在DBCS系列正式里,最充分之特性是有限配节长的方块字字符和均等字节长的英文字符并存于同同模仿编码方案里,因此他们写的先后为支持中文处理,必须要留心字串里之每一个字节的价,如果这个价值是超127底,那么就觉着一个双字节字符集里的字符出现了。那时候是受了加持,会编程的微处理器僧侣们都要每天念下面这咒语数百任何:

对等中国人们得到计算机时,已经没得以使的字节状态来表示汉字,况且有6000差不多独常因此汉字需要保留也。但是及时难不倒智慧之华夏老百姓,我们不客气地将那些127声泪俱下之后的奇异符号们直接取消掉,并且规定:一个低于127之字符的意义与本平,但简单独超过127的字符连在一起时,就意味着一个中国字,前面的一个字节(他称为高字节)从0xA1所以到
0xF7,后面一个字节(低字节)从0xA1及0xFE,这样我们就是可做有大约7000几近个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊之假名、日文的字母们还编上了,连以
ASCII
里当就一些数字、标点、字母都全重新编了片只字节长的编码,这就算是常常说之”全角”字符,而原来在127号以下的那些即使深受”半角”字符了。

      “一个字毕竟少个英文字符!一个字毕竟少单英文字符……”
         
     
因为及时相继国家还如中华这样来来同套好的编码标准,结果相互之间孰也未知晓谁之编码,谁吗不支持别人的编码,连大陆与台湾这么单隔了150海里,使用着同等栽语言的哥们地区,也独家下了不同的
DBCS
编码方案——当时底中国总人口想给电脑显示汉字,就务须作及一个”汉字系统”,专门就此来拍卖汉字的展示、输入的题材,但是非常台湾之无知封建人士形容的算命程序即使亟须加装另一样仿照支持
BIG5 
编码的啊”倚天汉字系统”才足以为此,装错了字符系统,显示就见面乱了法!这怎么处置?而且世界民族之林中还有那些一时就此不齐电脑的特困百姓,他们之文字以怎收拾?

华民看看如此十分科学,于是就管这种汉字方案叫做”GB2312″。GB2312 是针对
ASCII 的汉语扩展。

      真是计算机的巴比伦塔命题啊!
      正以这儿,大天使加百列及时出现了——一个被
ISO(国际标谁化组织)的国际集团控制下手解决此问题。他们用的点子充分简单:废了具有的地区性编码方案,重新来一个包了球上有着知识、所有字母和符号的编码!他们打算为她”Universal
Multiple-Octet Coded Character Set”,简称 UCS, 俗称 “UNICODE”。
      UNICODE
开始制订时,计算机的存储器容量极大地向上了,空间又为无成为问题了。于是
ISO
就直确定得用简单单字节,也就算是16各来统一意味着拥有的字符,对于ascii里的那些“半比赛”字符,UNICODE
包持其原编码不换,只是以该长由原先的8号扩展为16各类,而任何文化与言语的字符则遍又合并编码。由于”半角”英文符号只待为此到低8个,所以该高
8员永远是0,因此这种大气的方案于保存英文文本时会见多浪费一倍之半空中。

唯独中国的汉字太多矣,我们快就不怕发现出好多总人口之全名没有艺术于此从出来,特别是少数老会烦人家的国领导人(如朱镕基的“镕”字)。于是我们只好连续将
GB2312 没有动用的码位找出来老实不客气地用上。

     
这时候,从原有社会里活动过来的程序员开始发现一个竟之光景:他们的strlen函数靠不停歇了,一个汉字不再是一定给片独字符了,而是一个!是的,从
UNICODE
开始,无论是半角的英文字母,还是全角的方块字,它们都是联合之”一个字符”!同时,也还是联之”两个字节”,请留意”字符”和”字节约”两只术语的例外,“字节约”是一个8各的情理存贮单元,而“字符”则是一个文化相关的记号。在UNICODE
中,一个字符就是少数只字节。一个字毕竟少个英文字符的一时已快过去了。
         
     
从前又字符集存在时时,那些做多语言软件的柜蒙受上了好酷累,他们为当不同的国销售一律套软件,就不得不在区域化软件时为加持那个双字节字符集咒语,不仅使处处小心不要打错,还要管软件面临之契以不同的字符集中转来改去。UNICODE
对于他们来说是一个特别好的统筹兼顾解决方案,于是由 Windows NT 开始,MS
趁机将它的操作系统改了平普,把拥有的基本代码都改成成为了于是 UNICODE
方式工作之版,从这儿起,WINDOWS
系统终于任需要加装各种本土语言体系,就足以显得全世界上富有知识的字符了。
    但是,UNICODE
在制订时尚未设想和其余一样种现有的编码方案保持相当,这让 GBK 与UNICODE
在汉字之内码编排及全是休平等的,没有一样栽简易的算术方法可把文件内容从UNICODE编码和其他一样种编码进行转换,这种转移必须经查表来拓展。
    如前所述,UNICODE
是为此鲜个字节来表示为一个字符,他一共可组成产生65535不比之字符,这大概就足以覆盖世界上拥有知识之标记。如果还不够呢并未涉及,ISO已经准备了UCS-4方案,说简练了就是是四独字节来表示一个字符,这样咱们虽得组成产生21亿单不等的字符出来(最高位生任何用途),这大概可以为此到银河联邦成立那同样龙吧!
    UNICODE 来到时,一起赶到的还有计算机网络的兴起,UNICODE
如何当网络上传也是一个须要考虑的题材,于是面向传输的浩大 UTF(UCS
Transfer
Format)标准出现了,顾名思义,UTF8就是历次8只各类传输数据,而UTF16不怕是每次16独各,只不过为了传输时之可靠性,从UNICODE到
UTF时连无是直的应和,而是如了有算法和规则来转换。

后来或者不够用,于是干脆不再要求低字节一定是127号后的内码,只要第一只字节是超127不怕定位表示马上是一个汉字之开端,不管后面与的凡无是扩大字符集里的情节。结果扩展之后的编码方案被称为
GBK 标准,GBK 包括了 GB2312
的享有情节,同时还要追加了靠近20000单新的方块字(包括繁体字)和标记。

   
受到过网编程加持的处理器僧侣们都知,在网里传递信息时出一个生要紧之问题,就是对此数据高低位的解读道,一些计算机是采取低先发送的不二法门,例如我们PC机采用的
INTEL
架构,而另外一部分凡是应用高位先发送的法子,在网被交换数据时,为了审批双方于高低位的认识是否是一模一样的,采用了平等种怪省心的法门,就是在文本流的始发时向对方发送一个标志符——如果后的文本是高位在位,那就发送”FEFF”,反之,则发送”FFFE”。不信仰你得据此二进制方式打开一个UTF-X格式的文本,看看开头两独字节是休是即刻有限个字节?
    讲到此地,我们再顺便说说一个可怜知名的飞景象:当你当 windows
的记事本里新建一个文本,输入”联通”两单字之后,保存,关闭,然后又打开,你晤面发现及时简单独字既一去不返了,代之的是几单乱码!呵呵,有人说立刻虽是联通之所以拼不过移动的原由。

后来少数民族也只要用计算机了,于是我们再度扩展,又加以了几千独新的少数民族的字,GBK
扩成了 GB18030。从此以后,中华民族的学识就可于电脑时代中传承了。

    其实这是为GB2312编码和UTF8编码产生了编码冲撞的缘故。
    从网上引来一段落于UNICODE到UTF8的转换规则:
        Unicode
        UTF-8
        0000 – 007F
        0xxxxxxx
        0080 – 07FF
        110xxxxx 10xxxxxx
        0800 – FFFF
        1110xxxx 10xxxxxx 10xxxxxx
   
例如”汉”字的Unicode编码是6C49。6C49于0800-FFFF之间,所以若为此3字节模板:1110xxxx
10xxxxxx 10xxxxxx。将6C49状成二进制是:0110 1100 0100
1001,将之比较特流按三字节模板的旁方法分为0110 110001
001001,依次代替模板被的x,得到:1110-0110 10-110001 10-001001,即E6 B1
89,这即是其UTF8的编码。
   
而当您新建一个文件文件时,记事本的编码默认是ANSI,如果您于ANSI的编码输入汉字,那么他骨子里就是是GB系列的编码方式,在这种编码下,”联通”的内码是:
            c1 1100 0001
            aa 1010 1010
            cd 1100 1101
            a8 1010 1000
         
   
注意到了也?第一次单字节、第三季只字节的序幕部分的且是”110″和”10″,正好和UTF8规则里之两字节模板是一模一样的,于是又打开记事本时,记事本就误认为这是一个UTF8编码的文本,让咱拿第一个字节的110和亚单字节的10夺丢,我们就抱了”00001
101010″,再将诸位对一头,补及带的0,就取得了”0000 0000 0110
1010″,不好意思,这是UNICODE的006A,也便是聊写的假名”j”,而下的星星配节用UTF8解码之后是0368,这个字符什么也非是。这就算是只有”联通”两个字之公文并未主意于记事本里正常显示的来头。

中华底程序员们看这等同雨后春笋汉字编码的正儿八经是好之,于是通称他们叫做
“DBCS”(Double Byte Charecter Set
双许节字符集)。在DBCS系列正式里,最要命之特性是鲜字节长的字字符和平等许节长的英文字符并存于与同效编码方案里,因此他们写的主次为支持中文处
理,必须要注意字串里之各一个字节的值,如果此价值是超越127的,那么就是看一个双字节字符集里的字符出现了。那时候是受了加持,会编程的电脑僧侣们都使每天念下面这咒语数百整整:

   
而如您在”联通”之后多输入几只字,其他的配的编码不见得而恰是110同10开端之字节,这样再打开时,记事本就不见面坚持就是一个utf8编码的文书,而会为此ANSI的点子解读的,这时乱码又休起了。
         
   
好了,终于得回NICO的问题了,在数据库里,有n前缀的字串类型就是UNICODE类型,这种类型中,固定用半独字节来表示一个字符,无论这字符是汉字还是英文字母,或是别的什么。

“一个字毕竟少独英文字符!一个汉字毕竟少个英文字符……”

   
如果你如测试”abc汉字”这个串的长短,在没有n前缀的数据类型里,这个字串是7只字符的长,因为一个字相当给片独字符。而以发n前缀的数据类型里,同样的测试串长的函数将会见告知您是5只字符,因为一个汉字就是是一个字符。

因马上各个国家还如中国这样干来同效仿好的编码标准,结果相互之间孰也非晓谁之编码,谁吗无支持别人的编码,连大陆与台湾这么单相隔了150海里,使用着相同种植语言的小兄弟地区,也各自下了不同之
DBCS
编码方案——当时底华总人口怀念被电脑显示汉字,就不能不作及一个”汉字系统”,专门就此来拍卖汉字的来得、输入的题材,但是很台湾的无知封建人士形容的算命程序
就得加装另一样法支持 BIG5
编码的什么”倚天汉字系统”才得就此,装错了字符系统,显示就会乱了学!这怎么处置?而且世界民族之林中还有那些一时因故无上电脑的贫困百姓,他们之文字以怎
么办?

 

真是计算机的巴比伦塔命题啊!

恰好于这时,大天使加百列及时出现了——一个受 ISO
(国际标谁化组织)的国际组织决定下手解决是题材。他们利用的方很简短:废了具有的地区性编码方案,重新弄一个包括了地球上独具知识、所有字母和标记的编码!他们打算于其”Universal
Multiple-Octet Coded Character Set”,简称 UCS, 俗称 “UNICODE”。

UNICODE
开始制定时,计算机的存储器容量极大地开拓进取了,空间重为未化问题了。于是
ISO
就直接规定必须用少只字节,也便是16各项来归并意味着所有的字符,对于ascii里之那些”半竞”字符,UNICODE
包持其原编码不移,只是用那尺寸由原本的8号扩展为16号,而其他文化以及言语的字符则通双重合并编码。由于”半交锋”英文符号只待因此到低8各,所以其高
8个永远是0,因此这种大气的方案以保留英文文本时见面多浪费一加倍之半空中。

此刻,从老社会里活动过来的程序员开始察觉一个竟然的气象:他们的strlen函数靠不鸣金收兵了,一个字不再是相当给少数只字符了,而是一个!是
的,从 UNICODE
开始,无论是半角的英文字母,还是全角的汉字,它们都是统一的”一个字符”!同时,也都是联合之”两独字节”,请留意”字符”和”字节约”两单术语的不比,
“字节约”是一个8位之情理存贮单元,而”字符”则是一个文化有关的标记。在UNICODE
中,一个字符就是鲜单字节。一个中国字毕竟少只英文字符的秋都急匆匆过去了。

往出头字符集存在时时,那些做多语言软件的铺被上了那个可怜累,他们为在不同的国销售一律法软件,就不得不以区域化软件时为加持那个双字
节字符集咒语,不仅使处处小心不要为错,还要将软件被之亲笔以不同的字符集中转来改变去。UNICODE
对于他们吧是一个生好的一揽子解决方案,于是从 Windows NT 开始,MS
趁机将其的操作系统改了千篇一律全体,把具有的主干代码都改变成为了所以 UNICODE
方式行事之本子,从此时起,WINDOWS
系统终于任需要加装各种本土语言体系,就可展示全世界上富有知识的字符了。

不过,UNICODE 在制订时未尝设想与另外一样种植现有的编码方案保持兼容,这使
GBK 与UNICODE
在汉字之内码编排及了是免相同的,没有同种植简单的算术方法好将公文内容从UNICODE编码和其余一样栽编码进行转移,这种转移必须透过查表来开展。

如前所述,UNICODE
是因此半只字节来代表也一个字符,他一起可做有65535见仁见智之字符,这大概都好挂世界上有知识的标志。如果还不够啊没有关联,ISO已经准备了UCS-4方案,说简单了就是四个字节来表示一个字符,这样咱们就算可以整合出21亿独不同的字符出来(最高位来其它用途),这大概可以用到银河联邦成立那无异上吧!

UNICODE 来到时,一起到的还有电脑网络的兴起,UNICODE
如何当网达到传也是一个亟须考虑的题材,于是面向传输的森 UTF(UCS
Transfer
Format)标准出现了,顾名思义,UTF8就是每次8单各传输数据,而UTF16就是历次16独号,只不过为了传输时的可靠性,从UNICODE到
UTF时并无是直接的呼应,而是只要了有算法和规则来换。

遭遇了网络编程加持的微处理器僧侣们还知,在网里传递信息时发一个杀重要之题材,就是对于数据高低位的解读道,一些电脑是下低先发送的法,例如我们PC机采用的
INTEL
架构;而另一对凡应用高位先发送的措施。在网络被交换数据经常,为了对双方对高低位的认是否是相同的,采用了平栽非常便利的方法,就是当文本流的发端经常
向对方发送一个标志符——如果下的文件是高位在位,那就发送”FEFF”,反之,则发送”FFFE”。不信教你可为此二进制方式打开一个UTF-X格式的
文件,看看开头两单字节是匪是当时简单只字节?

下是Unicode和UTF-8转换的平整

Unicode

UTF-8

0000 – 007F

0xxxxxxx

0080 – 07FF

110xxxxx 10xxxxxx

0800 – FFFF

1110xxxx 10xxxxxx 10xxxxxx

比如说”汉”字之Unicode编码是6C49。6C49每当0800-FFFF之间,所以如果因此3字节模板:1110xxxx
10xxxxxx 10xxxxxx。将6C49描绘成二进制是:0110 1100 0100
1001,将是比特流按三字节模板的道岔方法分为0110 110001
001001,依次代替模板被之x,得到:1110-0110 10-110001 10-001001,即E6 B1
89,这就算是彼UTF8的编码。

说道到这边,我们更顺便说说一个十分有名的不测现象:当您于 windows
的记事本里新建一个文本,输入”联通”两个字之后,保存,关闭,然后再次打开,你晤面意识及时有限只字就熄灭了,代的的是几个乱码!呵呵,有人说立刻即是联通之所以拼不过移动的来由。

骨子里这是坐GB2312编码和UTF8编码产生了编码冲撞的来头。

当一个软件打开一个文件时,它使举行的率先桩事是控制这文件究竟是采取啊种字符集的啊种编码保留之。软件一般以三栽方法来控制文本的字符集及编码:

检测文件头标识,提示用户选择,根据早晚之条条框框猜测

顶标准的路子是检测文本最初步的几乎独字节,开头字节
Charset/encoding,如下表:

EF BB BF UTF-8

FE FF UTF-16/UCS-2, little endian

FF FE UTF-16/UCS-2, big endian

FF FE 00 00 UTF-32/UCS-4, little endian.

00 00 FE FF UTF-32/UCS-4, big-endian.

当你新建一个文书文件时,记事本的编码默认是ANSI(代表网默认编码,在中文系统中一般是GB系列编码),
如果你当ANSI的编码输入汉字,那么他骨子里就是是GB系列的编码方式,在这种编码下,”联通”的内码是:

c1 1100 0001

aa 1010 1010

cd 1100 1101

a8 1010 1000

小心到了为?第一亚单字节、第三季只字节的开场部分的还是”110″和”10″,正好与UTF8规则里之两字节模板是同样的,

于是乎当我们再次打开记事本时,记事本就误认为这是一个UTF8编码的文件,让咱把第一只字节的110暨亚只字节的10失丢,我们就是得了”00001
101010″,再将各位对一头,补上带的0,就抱了”0000 0000 0110
1010″,不好意思,这是UNICODE的006A,也不怕是稍稍写的假名”j”,而之后的个别许节用UTF8解码之后是0368,这个字符什么呢无是。这即是只有”联通”两个字之公文并未辙在记事本里正常显示的来由。

若是而你在”联通”之后多输入几只字,其他的配的编码不见得又刚好是110同10开端的字节,这样重复打开时,记事本就非会见坚持就是一个utf8编码的文本,而会就此ANSI的艺术解读的,这时乱码又未起了。

http://www.cnblogs.com/shilf/archive/2010/06/15/1758467.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图