字符集漫谈

来源:互联网 发布:java线程挂起 编辑:程序博客网 时间:2024/06/05 04:24

字符集是一个很头疼的问题,看了好多文档,太官方看起来费劲,今天发现了一个语言有趣的帖子,跟大家分享下:

 

一、漫谈版本

经常我们打开外国网站的时候出现乱码,又或者打开很多非英语的外国网站的时候,显示的都是口口口口口的字符,WordPress程序是用的UTF-8,很多cms用的是GB2312

● 为什么有这么多编码?

● UTF-8GB2312有什么区别?

● 我们在国内做网站是用UTF-8编码格式还是GB2312编码格式好?

1.    各种编码的来历

可能很多同学一直对字符的各种编码方式懵懵懂懂,根本搞不清为什么他们有这么多编码。

1)    ANSI编码

其实在很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为字节

开始计算机只在美国用。八位的字节一共可以组合出25628次方)种不同的状态。他们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端、打印机遇上约定好的这些字节被传过来时,就要做一些约定的动作。遇上00×10,终端就换行,遇上0×07,终端就向人们嘟嘟叫,例好遇上0×1b,打印机就打印反白的字,或者终端就用彩色显示字母。他们看到这样很好,于是就把这些0×20以下的字节状态称为"控制码"。他们又把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第127号,这样计算机就可以用不同字节来存储英语的文字了。大家看到这样,都感觉很好,于是大家都把这个方案叫做 ANSI "Ascii"编码(American Standard Code for InformationInterchange,美国信息互换标准代码)。当时世界上所有的计算机都用同样的ASCII方案来保存英文文字。

2)    扩展ANSI编码

后来,就像建造巴比伦塔一样,世界各地的都开始使用计算机,但是很多国家用的不是英文,他们的字母里有许多是ASCII里没有的,为了可以在计算机保存他们的文字,他们决定采用127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128255这一页的字符集被称扩展字符集。从此之后,贪婪的人类再没有新的状态可以用了,美国当时估计也没想到还有别的国家要用计算机的。

3)    GB2312编码

当天朝人们得到计算机时,已经没有可以利用的字节状态来表示汉字,况且有6000多个常用汉字需要保存呢。天朝人民就不客气地把那些127号之后的奇异符号们直接取消掉。

规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA10xFE,这样我们就可以组合出大约7000多个简体汉字了。

在这些编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的全角字符,而原来在127号以下的那些就叫"半角"字符了。于是就把这种汉字方案叫做 “GB2312”GB2312是对 ASCII 的中文扩展。

4)    GBK GB18030编码

但是天朝的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,特别是某些天朝领导的名字要是打不出很麻烦的。于是我们不得不继续把 GB2312没有用到的码位找出来老实不客气地用上。

后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。

后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK扩成了 GB18030。从此之后,天朝民族的文化就可以在计算机时代中传承了。

在这个标准里,最大的特点是两字节长的汉字字符和一字节长的英文字符并存于同一套编码方案里,因此他们写的程序为了支持中文处理,必须要注意字串里的每一个字节的值,如果这个值是大于127的,那么就认为一个双字节字符集里的字符出现了。

那时候凡是受过编程学习的程序员都要每天念下面这个咒语数百遍的折磨:

一个汉字算两个英文字符!一个汉字算两个英文字符……”

5)    UNICODE编码

因为当时各个国家都像天朝这样搞出一套自己的编码标准,结果互相之间谁也不懂谁的编码,谁也不支持别人的编码,连大陆和台湾这样只相隔了150海里,使用着同一种语言的兄弟地区,也分别采用了不同的编码方案:

当时的天朝人想让电脑显示汉字,就必须装上一个汉字系统。专门用来处理汉字的显示、输入的问题。但是那个装台湾的人士写的程序就必须加装另一套支持 BIG5 编码的倚天汉字系统才可以用,装错了字符系统,显示就会乱了套!这怎么办?而且世界民族中还有那些暂时用不上电脑的穷苦人民,他们的文字又怎么办?

正在这时,天使及时出现了——一个叫 ISO(国际标谁化组织)的国际组织决定着手解决这个问题。他们采用的方法很简单:废了所有的地区性编码方案,重新搞一个包括了地球上所有文化、所有字母和符号的编码!他们打算叫它 UCS,俗称 UNICODE Universal Multiple-Octet Coded CharacterSet)。

UNICODE中,一个汉字算两个英文字符的时代已经快过去了。

无论是半角的英文字母,还是全角的汉字,它们都是统一的“一个字符”!同时,也都是统一的“两个字节”。

6)    UTF-8UTF-16

UNICODE 来到时,一起到来的还有计算机网络的兴起,UNICODE如何在网络上传输也是一个必须考虑的问题,于是面向传输的众多 UTFUCS TransferFormat)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODEUTF时并不是直接的对应,而是要过一些算法和规则来转换。

7)    未来的UCS-4

如前所述,UNICODE是用两个字节来表示为一个字符,他总共可以组合出65535不同的字符,这大概已经可以覆盖世界上所有文化的符号。如果还不够也没有关系,ISO已经准备了UCS-4方案,说简单了就是四个字节来表示一个字符,这样我们就可以组合出21亿个不同的字符出来(最高位有其他用途),这大概可以用到天朝成立银河联邦成立那一天吧!

2.    为什么有些网站打开有时候会是乱码

网页乱码是浏览器(如IE等)对HTML网页解释时形成的。如果在浏览网站网页的代码写错语系(比较少见),有形如:

<HTML>

<HEAD>

<METACONTENT=“text/htmlcharset=ISO-8859-1”></HEAD>……

</HTML>

的语句,浏览器在显示此页时,就会出现乱码。因为浏览器会将此页语种辨认为欧洲语系

解决的办法是将语种“ISO-8859-1”改为GB2312,如果是繁体网页则改为BIG5

还有一种可能比较大,就是网页并没有标明他用的是何种语系,即没有<META CONTENT=“text/htmlcharset=XXXXX“>这一行,而你的计算机默认也不是这种语系,比方我们访问某些日文网站,经常出现这个问题。这个主要是由于程序员是面向当地的人开发的网站,由于当地都是默认语系,所以没有乱码种情况,而你是外来人,你的操作系统本身默认不是当地的语系,所以要手动改语系。

至于出现口口口口口口这种情况

这是由于网站并没有采用UTF-8编码而是采用的当地的编码,如蒙古语的,阿拉伯语的编码,你的计算机中并没有这种编码,所以不能识别。解决办法是,事先为浏览器安装多语言支持包(例如在安装IE时要安装多语言支持包),这样在浏览网页出现乱码时,就可以在浏览器中选择菜单栏下的查看”/“编码”/“自动选择”/蒙古),如为繁体中文则选择查看”/“编码”/“自动选择”/阿拉伯语,其它语言依此类推选择相应的语系,这样可消除网页乱码现象。

3.    目前开发网站用什么编码比较好

我们一般通俗的理解为:

1)    UTF-8是世界性通用代码,也完美的支持中文编码,如果我们做的网站能让国外用户正常的访问,就最好用UTF-8

2)    GB2312属于中文编码,主要针对国内用户使用,如果国外用户访问GB2312编码的网站就会变乱码。

3)    网友的反馈一般觉得是用UTF-8GB2312要多很多,大家都比较赞同用UTF-8。从一张外国网站的调查也可看得出:

由此图可以看出,2001-2008年期间,GB2312编码的使用情况虽然幅度不大,但还是在稳定上升的;蓝色的线表示出用UTF-8的网站越来越多了。

4)    我挑选了国内部分几个大的门户网站,看看他们用的是哪种编码格式:

5)    也许有同学就会问了为什么国内几个网站用GB2312反而更多些呢。

我也对这个疑问进行了思考,我觉得。应该有3种原因:

a)    国内这些网站本身历史也比较长,开始使用的就是 GB2312编码,现在改成 UTF-8(以前的网页)转换的难度和风险太大。

b)    UTF-8编码的文件比GB2312更占空间一些,虽然目前的硬件环境下可以忽略,但是这些门户网站为了减少服务器负载基本上所有的页面都生成了静态页,UTF-8保存起来文件会比较大,对于门户级别的网站每天生成的文件量还是非常巨大,带来的存储成本相应提高。

c)    由于UTF-8的编码比GB2312解码的网络传输数据量要大,对于门户级别的网站来说。这个无形之间就要增大带宽,用GB2312对网络流量无疑是最好的优化。

所以在新做站的情况下,建议还是选择UTF-8比较好。因为没有上面那些原因,兼容为上策。

 

官方版

1.      基础知识

计算机中储存的信息都是用二进制数表示的;而我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果。通俗的说,按照何种规则将字符存储在计算机中,如'a'用什么表示,称为"编码";反之,将存储在计算机中的二进制数解析显示出来,称为"解码",如同密码学中的加密和解密。在解码过程中,如果使用了错误的解码规则,则导致'a'解析成'b'或者乱码。

字符集(Charset:是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。

字符编码(Character Encoding:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项基本技术。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用元件(硬件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。

2.    常用字符集和字符编码

常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。

2.1. ASCII字符集&编码

ASCIIAmerican Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以勉强显示其他西欧语言。它是现今最通用的单字节编码系统(但是有被Unicode追上的迹象),并等同于国际标准ISO/IEC 646

ASCII字符集:主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号)。

ASCII编码:将ASCII字符集转换为计算机可以接受的数字系统的数的规则。使用7位(bits)表示一个字符,共128字符;但是7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。ASCII字符集映射到数字编码规则如下图所示:


1 ASCII编码表

2扩展ASCII编码表

ASCII的最大缺点是只能显示26个基本拉丁字母、阿拉伯数目字和英式标点符号,因此只能用于显示现代美国英语(而且在处理英语当中的外来词如naïvecaféélite等等时,所有重音符号都不得不去掉,即使这样做会违反拼写规则)。而EASCII虽然解决了部份西欧语言的显示问题,但对更多其他语言依然无能为力。因此现在的苹果电脑已经抛弃ASCII而转用Unicode

2.2. GBXXXX字符集&编码

计算机发明之处及后面很长一段时间,只用应用于美国及西方一些发达国家,ASCII能够很好满足用户的需求。但是当天朝也有了计算机之后,为了显示中文,必须设计一套编码规则用于将汉字转换为计算机可以接受的数字系统的数。

天朝专家把那些127号之后的奇异符号们(即EASCII)取消掉,规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA10xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。

上述编码规则就是GB2312GB2312GB2312-80中国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,又称GB0,由中国国家标准总局发布,198151实施。GB2312编码通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB2312GB2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。对于人名古汉语等方面出现的罕用字GB2312不能处理,这导致了后来GBKGB 18030汉字字符集的出现。下图是GB2312编码的开始部分(由于其非常庞大,只列举开始部分,具体可查看GB2312简体中文编码表):

3 GB2312编码表的开始部分

由于GB 2312-80只收录6763个汉字,有不少汉字,如部分在GB 2312-80推出以后才简化的汉字(如""),部分人名用字(如中国前总理朱镕基""字),台湾及香港使用的繁体字日语朝鲜语汉字等,并未有收录在内。于是厂商微软利用GB 2312-80未使用的编码空间,收录GB 13000.1-93全部字符制定了GBK编码。根据微软资料,GBK是对GB2312-80的扩展,也就是CP936字码表 (Code Page 936)的扩展(之前CP936GB 2312-80一模一样),最早实现于Windows 95简体中文版。虽然GBK收录GB 13000.1-93的全部字符,但编码方式并不相同。GBK自身并非国家标准,只是曾由国家技术监督局标准化司、电子工业部科技与质量监督司公布为"技术规范指导性文件"。原始GB13000一直未被业界采用,后续国家标准GB18030技术上兼容GBK而非GB13000

GB 18030,全称:国家标准GB18030-2005《信息技术中文编码字符集》,是中华人民共和国现时最新的内码字集,是GB 18030-2000《信息技术信息交换用汉字编码字符集基本集的扩充》的修订版。与GB 2312-1980完全兼容,与GBK基本兼容,支持GB 13000Unicode的全部统一汉字,共收录汉字70244个。GB 18030主要有以下特点:

·        UTF-8相同,采用多字节编码,每个字可以由1个、2个或4个字节组成。

·        编码空间庞大,最多可定义161万个字符。

·        支持中国国内少数民族的文字,不需要动用造字区。

·        汉字收录范围包含繁体汉字以及日韩汉字

4 GB18030编码总体结构

本规格的初版使中华人民共和国信息产业部电子工业标准化研究所起草,由国家质量技术监督局于2000317发布。现行版本为国家质量监督检验总局和中国国家标准化管理委员会于2005118发布,200651实施。此规格为在中国境内所有软件产品支持的强制规格。

2.3. BIG5字符集&编码

Big5,又称为大五码五大码,是使用繁体中文(正体中文)社区中最常用的电脑汉字字符集标准,共收录13,060个汉字。中文码分为内码交换码两类,Big5属中文内码,知名的中文交换码有CCCIICNS11643Big5虽普及于台湾香港澳门等繁体中文通行区,但长期以来并非当地的国家标准,而只是业界标准倚天中文系统Windows等主要系统的字符集都是以Big5为基准,但厂商又各自增加不同的造字与造字区,派生成多种不同版本。2003Big5被收录到CNS11643中文标准交换码的附录当中,取得了较正式的地位。这个最新版本被称为Big5-2003

Big5码是一套双字节字符集,使用了双八码存储方法,以两个字节来安放一个字。第一个字节称为"高位字节",第二个字节称为"低位字节""高位字节"使用了0x81-0xFE"低位字节"使用了0x40-0x7E,及0xA1-0xFE在Big5的分区中:

0x8140-0xA0FE

保留给用户自定义字符(造字区)

0xA140-0xA3BF

标点符号、希腊字母及特殊符号,包括在0xA259-0xA261,安放了九个计量用汉字:兙兛兞兝兡兣嗧瓩糎。

0xA3C0-0xA3FE

保留。此区没有开放作造字区用。

0xA440-0xC67E

常用汉字,先按笔划再按部首排序。

0xC6A1-0xC8FE

保留给用户自定义字符(造字区)

0xC940-0xF9D5

次常用汉字,亦是先按笔划再按部首排序。

0xF9D6-0xFEFE

保留给用户自定义字符(造字区)

 

3.    伟大的创想Unicode

——不得不单独说Unicode

像天朝一样,当计算机传到世界各个国家时,为了适合当地语言和字符,设计和实现类似GB232/GBK/GB18030/BIG5的编码方案。这样各搞一套,在本地使用没有问题,一旦出现在网络中,由于不兼容,互相访问就出现了乱码现象。

为了解决这个问题,一个伟大的创想产生了——UnicodeUnicode编码系统为表达任意语言的任意字符而设计。它使用4字节的数字来表达每个字母、符号,或者表意文字(ideograph)。每个数字代表唯一的至少在某种语言中使用的符号。(并不是所有的数字都用上了,但是总数已经超过了65535,所以2个字节的数字是不够用的。)被几种语言共用的字符通常使用相同的数字来编码,除非存在一个在理的语源学(etymological)理由使不这样做。不考虑这种情况的话,每个字符对应一个数字,每个数字对应一个字符。即不存在二义性。不再需要记录"模式"了。U+0041总是代表'A',即使这种语言没有'A'这个字符。

计算机科学领域中,Unicode统一码万国码单一码标准万国码)是业界的一种标准,它可以使电脑得以体现世界上数十种文字的系统。Unicode是基于通用字符集Universal Character Set)的标准来发展,并且同时也以书本的形式[1]对外发表。Unicode还不断在扩增,每个新版本插入更多新的字符。直至目前为止的第六版,Unicode就已经包含了超过十万个字符(在2005Unicode的第十万个字符被采纳且认可成为标准之一)、一组可用以作为视觉参考的代码图表、一套编码方法与一组标准字符编码、一套包含了上标字、下标字等字符特性的枚举等。Unicode组织(The Unicode Consortium)是由一个非营利性的机构所运作,并主导 Unicode的后续发展,其目标在于:将既有的字符编码方案以Unicode编码方案来加以取代,特别是既有的方案在多语环境下,皆仅有有限的空间以及不兼容的问题。

可以这样理解:Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三种字符编码方案。

3.1.UCS & UNICODE

通用字符集UniversalCharacter SetUCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。历史上存在两个独立的尝试创立单一字符集的组织,即国际标准化组织(ISO)和多语言软件制造商组成的统一码联盟。前者开发的 ISO/IEC 10646 项目,后者开发的统一码项目。因此最初制定了不同的标准。

1991前后,两个项目的参与者都认识到,世界不需要两个不兼容的字符集。于是,它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出U+10FFFFUCS-4编码赋值,以使得两者保持一致。两个项目仍都存在,并独立地公布各自的标准。但统一码联盟和ISO/IEC JTC1/SC2都同意保持两者标准的码表兼容,并紧密地共同调整任何未来的扩展。在发布的时候,Unicode一般都会采用有关字码最常见的字型,但ISO 10646一般都尽可能采用Century字型

3.2.UTF-32

上述使用4字节的数字来表达每个字母、符号,或者表意文字(ideograph),每个数字代表唯一的至少在某种语言中使用的符号的编码方案,称为UTF-32UTF-32又称UCS-4是一种将Unicode字符编码的协定,对每个字符都使用4字节。就空间而言,是非常没有效率的。

这种方法有其优点,最重要的一点就是可以在常数时间内定位字符串里的第N个字符,因为第N个字符从第4×Nth个字节开始。虽然每一个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得广泛。

3.3.UTF-16

尽管有Unicode字符非常多,但是实际上大多数人不会用到超过前65535个以外的字符。因此,就有了另外一种Unicode编码方式,叫做UTF-16(因为16 = 2字节)UTF-160–65535范围内的字符编码成2个字节,如果真的需要表达那些很少使用的"星芒层(astral plane)"内超过这65535范围的Unicode字符,则需要使用一些诡异的技巧来实现。UTF-16编码最明显的优点是它在空间效率上比UTF-32高两倍,因为每个字符只需要2个字节来存储(除去65535范围以外的),而不是UTF-32中的4个字节。并且,如果我们假设某个字符串不包含任何星芒层中的字符,那么我们依然可以在常数时间内找到其中的第N个字符,直到它不成立为止这总是一个不错的推断。其编码方法是:

·        如果字符编码U小于0x10000,也就是十进制的065535之内,则直接使用两字节表示;

·        如果字符编码U大于0x10000,由于UNICODE编码范围最大为0x10FFFF,从0x100000x10FFFF之间共有0xFFFFF个编码,也就是需要20bit就可以标示这些编码。用U'表示从0-0xFFFFF之间的值,将其前 10 bit作为高位和16 bit的数值0xD800进行逻辑or操作,将后10 bit作为低位和0xDC00逻辑or操作,这样组成的 4byte就构成了U的编码。

对于UTF-32UTF-16编码方式还有一些其他不明显的缺点。不同的计算机系统会以不同的顺序保存字节。这意味着字符U+4E2DUTF-16编码方式下可能被保存为4E 2D或者2D 4E,这取决于该系统使用的是大尾端(big-endian)还是小尾端(little-endian)(对于UTF-32编码方式,则有更多种可能的字节排列。)只要文档没有离开你的计算机,它还是安全的——同一台电脑上的不同程序使用相同的字节顺序(byte order)。但是当我们需要在系统之间传输这个文档的时候,也许在万维网中,我们就需要一种方法来指示当前我们的字节是怎样存储的。不然的话,接收文档的计算机就无法知道这两个字节4E 2D表达的到底是U+4E2D还是U+2D4E

为了解决这个问题,多字节的Unicode编码方式定义了一个"字节顺序标记(Byte OrderMark)",它是一个特殊的非打印字符,你可以把它包含在文档的开头来指示你所使用的字节顺序。对于UTF-16,字节顺序标记是U+FEFF。如果收到一个以字节FF FE开头的UTF-16编码的文档,你就能确定它的字节顺序是单向的(one way)的了;如果它以FE FF开头,则可以确定字节顺序反向了。

3.4.UTF-8

UTF-88-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码定长码),也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。因此,它逐渐成为电子邮件网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组IETF)要求所有互联网协议都必须支持UTF-8编码。

UTF-8使用一至四个字节为每个字符编码:

1)      128US-ASCII字符只需一个字节编码(Unicode范围由U+0000U+007F)。

2)     带有附加符号拉丁文希腊文西里尔字母亚美尼亚语希伯来文阿拉伯文叙利亚文它拿字母则需要二个字节编码(Unicode范围由U+0080U+07FF)。

3)     其他基本多文种平面BMP)中的字符(这包含了大部分常用字)使用三个字节编码。

4)     其他极少使用的Unicode辅助平面的字符使用四字节编码。

在处理经常会用到的ASCII字符方面非常有效。在处理扩展的拉丁字符集方面也不比UTF-16差。对于中文字符来说,比UTF-32要好。同时,(在这一条上你得相信我,因为我不打算给你展示它的数学原理。)由位操作的天性使然,使用UTF-8不再存在字节顺序的问题了。一份以utf-8编码的文档在不同的计算机之间是一样的比特流。

总体来说,在Unicode字符串中不可能由码点数量决定显示它所需要的长度,或者显示字符串之后在文本缓冲区中光标应该放置的位置;组合字符、变宽字体、不可打印字符和从右至左的文字都是其归因。所以尽管在UTF-8字符串中字符数量与码点数量的关系比UTF-32更为复杂,在实际中很少会遇到有不同的情形。

优点:

·        UTF-8ASCII的一个超集。因为一个纯ASCII字符串也是一个合法的UTF-8字符串,所以现存的ASCII文本不需要转换。为传统的扩展ASCII字符集设计的软件通常可以不经修改或很少修改就能与UTF-8一起使用。

·        使用标准的面向字节的排序例程对UTF-8排序将产生与基于Unicode代码点排序相同的结果。(尽管这只有有限的有用性,因为在任何特定语言或文化下都不太可能有仍可接受的文字排列顺序。)

·        UTF-8UTF-16都是可扩展标记语言文档的标准编码。所有其它编码都必须通过显式或文本声明来指定。

·        任何面向字节字符串搜索算法都可以用于UTF-8的数据(只要输入仅由完整的UTF-8字符组成)。但是,对于包含字符记数的正则表达式或其它结构必须小心。

·        UTF-8字符串可以由一个简单的算法可靠地识别出来。就是,一个字符串在任何其它编码中表现为合法的UTF-8的可能性很低,并随字符串长度增长而减小。举例说,字符值C0,C1,F5FF从来没有出现。为了更好的可靠性,可以使用正则表达式来统计非法过长和替代值(可以查看W3 FAQ:Multilingual Forms上的验证UTF-8字符串的正则表达式)。

缺点:

因为每个字符使用不同数量的字节编码,所以寻找串中第N个字符是一个O(N)复杂度的操作 — 即,串越长,则需要更多的时间来定位特定的字符。同时,还需要位变换来把字符编码成字节,把字节解码成字符。

0 0
原创粉丝点击