《字符编码测试总结》word版.doc_第1页
《字符编码测试总结》word版.doc_第2页
《字符编码测试总结》word版.doc_第3页
《字符编码测试总结》word版.doc_第4页
《字符编码测试总结》word版.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

字符编码测试总结字符编码测试总结2011-05-23 02:40 1.字符编码基础知识1.1.字符编码基本概念现代编码模型的编码思想包括:有什么字符、他们的编号、这些编号如何编码成一系列的码元,以及最后这些单元如何编码为8位字节流。对应于如下术语:1)字符表一个系统所支持的所有抽象字符的总合。2)编码字符集定义了如何使用称为码点的非负整数集表示一个字符集,一个整数对应一个抽象的字符。3)字符编码形式定义将编码字符集的整数代码转换成有限大小整数代码值以利于使用固定位的二进制表示数字的形式的系统存储。例如使用8位或16位单元存储数字信息。字符编码形式定义了如何用单个或多个码值表示码点的方法。例如utf8是一种编码形式,utf-16则是另一种编码形式。4)字符编码机制定义固定大小的整数代码如何映射到基于8位字节数据的文件系统存储或者基于8位字节网络传输。在多数使用unicode的场合,一个简单的字符编码机制用来指定每个整数的字节顺序是大字节在先顺序还是小字节在先顺序。还有其他复杂的字符编码机制。1.2.字符编码发展字符编码的历史大致可以分为三个阶段:1)ascii阶段刚开始只支持英语,其他语言不能够在计算机上存储和显示。使用一个字节来存一个字符。2)ansi编码(本地化)为使计算机支持更过语言,通过使用0x800xFF范围的2个字节来表示1个字符。不同的国家和地区制定了不同的标准,由此产生了各种各样的编码标准,如gb2312、big5、jis等。这些使用两个字节来表示一个字符的各种汉字延伸编码方式,称为ansi编码。3)Unicode阶段(国际化)为了使国际间信息交流更加方便,国际组织制定了unicode字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode仅仅制定了字符集,用来给unicode编码的标准有utf-7、utf-8、utf-16、unicodeLittle、unicodebig等。1.3.主要编码1.3.1.Ascii ascii全称美国信息互换标准代码(american standard code for information interchage)。主要用于显示现代英语和其他西欧语言,是现今最通用的单字节编码,等于国标标准iso 646。包含控制字符32个和可打印字符94个。编码单元为8位,取值单位从0x00-0x7F,最高为0。1.3.2.汉字编码汉字编码均采用双字节编码,编码单元为8位。.Gb2312-80 Gb2312是对ascii的中文扩展,是中华人民共和国国家标准汉字信息交换用编码。收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母等共7445个图形字符。其中汉字以外的图形字符682个,汉字6763个。为了与系统中基本的ascii字符集区分开,所有汉字编码的每个字节的第一位都是1。Gb2312的汉字编码规则是:第一个字节的值在0xB0到0xF7之间,第二个字节的值在0xA0到0xFE之间。但是gb2312收录的汉字太少,以致很多常用字都没有收录,如朱镕基的镕字。为了解决这些问题,以及配合unicode的实施,全国信息技术化技术委员会制定了gb13000,即gbk。Gbk向下与gb2312完全兼容,向上支持iso-10646国际标准。.Gbk Gbk包含了20902个汉字,其编码范围是0x8140-0xfefe,剔除高位0x80的字位。收录汉字包括:1)gb2312中全部汉字、非汉字字符2)big5中的全部汉字3)与iso-10646相应的国家标准gb13000中的其他cjk汉字4)其他汉字、部首、符号等。其分布图如下:其编码区分成三个部分:1)汉字区包括a)Gbk/2:0xb0a1-f7fe,收录gb2312汉字6763个,按原序排列,0xd7fa-0xd7fe为空洞。b)Gbk/3:0x8140-a0fe,收录cjk汉字6080个,0x817f-0xa07f为空洞c)Gbk/4:0xaa40-fea0,收录cjk汉字和增补汉字8160个,0xaa7f-0xfe7f为空洞2)图形符号区包括a)Gbk/1:0xa1a1-0xa9fe,除gb2312的符号外,还增补了其他符号b)Gbk/5:0xa840-0xa9a0,扩充非汉字区3)用户自定义区.Gb18030-2000 GB18030-2000是2000年推出的国家标准。它可以视为GBK的升级,因为它主要增加了Unicode 3.0中新增的一些字符。除了GBK的字符,它能表示UNICODE中所有的字符。中国出售的所有软件产品都要求支持GB18030。GB18030与GBK完全兼容,除了欧元符号:在GB18030中是A2E3,在GBK中是0x80。采用单字节、双字节和四字节三种方式对字符编码,编码范围如下:1)单字节:0x00-0x7f 2)双字节:0x81-0xfe+0x40-0x7e,0x80-0xfe 3)四个字节:0x81-0xfe+0x30-0x39+0x81-0xfe+0x30-0x39 .Big5 Big5又称五大码,是使用繁体中文字社群众最常用的计算机汉字字符集标准,由台湾5家大公司的方案拼凑而成。Big5共收录13053个中文字,其中有两个字重码,为兀(0xa461及0xc94a)和嗀(0xdcd1-0xddfc)。Big5使用双八码存储方式,以两个字节来安放一个字。高位字节使用了0xa1-0xf9,低位字节使用了0x40-0x7e及0xa1-0xfe。原始的BIG-5只包括一些常用的字,甚至不包括日文的假名等,在实际的应用中很多系统给BIG-5加上了自己的扩展。例如,MS code page 950,欧元符号A3E1。1.3.3.Unicode Unicode是一个大一统的方案,它是制定的编码机制,要将全世界常用文字都函括进去。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。随着计算机工作能力的增强,Unicode也在面世以来的十多年里得到普及。但自从unicode2.0开始,unicode采用了与ISO 10646-1相同的字库和字码,ISO也承诺ISO10646将不会给超出0x10FFFF的UCS-4编码赋值,使得两者保持一致。Unicode的编码方式与ISO 10646的通用字符集(Universal Character Set,UCS)概念相对应,目前的用于实用的Unicode版本对应于UCS-2,使用16位的编码空间。也就是每个字符占用2个字节,基本满足各种语言的使用。实际上目前版本的Unicode尚未填充满这16位编码,保留了大量空间作为特殊使用或将来扩展。Unicode和ucs只是分配整数给字符的编码表,即只是一个编码字符集合。现在存在好几种将一个字符表示为若干个字节的方法。最显而易见的方法是将unicode文本存储为2个或4个字节序列的串。这两种方法的正式名称为ucs-2和ucs-4。但是在unix下使用ucs-2或ucs-4会导致非常严重的问题。用这些编码的字符串会包含一些特殊的字符,比如message或/,他们在文件名和其他c库函数里都有特别的含义。另外,大多数使用ascii文件的unix下的工具,如果不进行重大修改是无法读取16位的字符的。基于这些原因,在文件名,文本文件、环境变量等地方,ucs-2不适合作为unicode的外部编码。因此需要一种新的编码方案称为utf(unicode transfer format)运用在unix/linux环境中。Utf-7,utf-8,utf-16都是广泛接受的方案。Rfc2781和rfc3629定义了utf-8和utf-16的编码方式。.Utf-8 Utf-8就是以8位为单元对ucs-2进行编码。从ucs-2到utf-8的编码方式如下:U-00000000-U-0000007F:0xxxxxxx U-00000080-U-000007FF:110xxxxx 10xxxxxx U-00000800-U-0000FFFF:1110xxxx 10xxxxxx 10xxxxxx U-00010000-U-001FFFFF:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx U-00200000-U-03FFFFFF:111110 xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx U-04000000-U-7FFFFFFF:1111110 x10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx Utf-8有如下特性:1)UCS字符U+0000到U+007F(ASCII)被编码为字节0x00到0x7F(ASCII兼容)。这意味着只包含7位ASCII字符的文件在ASCII和UTF-8两种编码方式下是一样的。2)所有U+007F的UCS字符被编码为一个多个字节的串,每个字节都有标记位集。因此,ASCII字节(0x00-0x7F)不可能作为任何其他字符的一部分.3)表示非ASCII字符的多字节串的第一个字节总是在0xC0到0xFD的范围里,并指出这个字符包含多少个字节。多字节串的其余字节都在0x80到0xBF范围里。这使得重新同步非常容易,并使编码无国界,且很少受丢失字节的影响.4)可以编入所有可能UCS代码5)UTF-8编码字符理论上可以最多到6个字节长,然而16位BMP字符最多只用到3字节长。6)Bigendian UCS-4字节串的排列顺序是预定的.7)字节0xFE和0xFF在UTF-8编码中从未用到..Uft-16 Utf-16是以16位为编码单元的,在范围u+0000到u+ffff间的码点使用一个单一的16位编码单元表示;而在范围u+10000到u+10FFFF间的码点则使用一对16位编码单元表示,称作代理对。Utf-16优化了基本多语言平面(bmp)中字符的表示,即位于u+0000到u+FFFF范围内的字符。该范围包含了目前世界上所使用的书写系统中的绝大数字符,每个字符只需要一个16位的编码单元。对于基本多语言平面,utf-16可作为固定宽度的编码格式来有效使用。但是对于增补字符,utf-16需要两个16位的编码单元,意味着正式的utf-16是一个变宽的编码格式。Utf-16是早期unicode遗留下的历史产物,原本被设计成具有固定宽度的16位编码格式,为支持超过u+ffff的增补字符,设立了代理机制。.Utf-32 Utf-32是一种最简单的unicode编码格式。每个unicode码点直接被表示为一个32位的编码单元。Utf-32是一种固定宽度的字符编码格式。每个utf-32编码单元的值与unicode码点的值完全相同。1.4.Tips 1.4.1.编码字节序big endian和little endian是CPU处理多字节数的不同方式。例如汉字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。如果将49写在前面,就是little endian。endian这个词出自格列佛游记。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,一个皇帝送了命,另一个丢了王位。我们一般将endian翻译成字节序,将big endian和little endian称作大尾和小尾。对于任何字符编码,编码单元的顺序是由编码方案指定的,与endian无关。例如gbk的编码单元是字节,用两个字节表示一个汉字,这两个字节的顺序是固定的,不受cpu字节序的影响。Utf-16的编码单元是word,word之间的顺序是编码方案指定的,word内部的字节排列才会收到endian的影响。Utf-8也是以字节为编码单元,没有字节序的问题。一个使用utf-16编码的文件如何进行解释呢?以一个例子来说明,打开记事本,写上一段文字,然后另存,在保存的对话框中可以看到有四种编码方式可以选择,分别是:ansi,unicode,unicode big endian和utf-8。Ansi是默认编码方式,也是系统的默认编码方式,由缺省代码页决定。Utf-8不用解释了。Unicode和unicode big endian都是utf-16编码的两种,区别在于前者采用little endian,后者采用big endian。还有一种方式采用bom标记字节序列,bom即byte order mark,是一个有点小聪明的想法。在ucs编码中有一个叫做zero width no-break space的字符,他的编码是feff。而feff在ucs中是不存在的字符,所以不应该出现在实际传输中。Ucs规范建议我们在传输字节流前,西安传输字符zero width no-break space。这样如果接受者收到fef,就表明这个字节流是big-endian;如果fffe,就表明这个字节流是little-endian的。ABC这三个字符用各种方式编码后的结果如下:utf-16be 00 41 00 42 00 43 utf-16le 41 00 42 00 43 00 utf-16(bom be)fe ff 00 41 00 42 00 43 utf-16(bom le)ff fe 41 00 42 00 43 00 utf-16(不带bom)00 41 00 42 00 43 1.4.2.Windows代码页Unicode推出后,microsoft将windows的内核都改成支持unicode字符集。但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如gbk,windows不可能不支持现有的编码而全部改用unicode。Windows使用代码页来适应各个国家和地区。Gbk对应的code page是cp936,gb18030的code page为cp54936。但是由于gb18030有一部分四字节编码,而windows的代码页只支持单字节和双字节编码,故cp54936是无法真正使用的。Windows可以同时支持多个代码页,只要文件能够说明自己使用什么编码,用户又安装了对应的代码页,windows就能正确显示,例如在html文件中指定charset。Windows中有缺省代码页的概念,可以通过控制面板的区域选项设置,其作用是缺省用什么编码来解释字符。Windows的记事本的存储格式有一项是ansi,其实就是按照缺省代码页的编码方式保存。2.网页编码方式2.1.url编码基础知识一个http请求需要经过如下几个环节:1)浏览器把url以及提交的内容经过编码后发送给服务器2)服务器处理完毕后将结果编码返回给浏览器3)浏览器按照指定的编码显示网页一个完整的url由如下方式组成:域名:端口/contextPath/servletPath/pathInfo?queryString其中pathInfo和queryString是需要编码的部分。Rfc1738中定义了url的语法语义,限制了url中可以出现的字符。对于不可在url中出现的字符需要按照一定的方式进行编码,叫做url encode。需要进行encode的符号包括如下:1)ascii中的控制字符,原因很简单,因为他们是不可见的,范围为00-1F和7F;2)非ascii字符,比如中文字符等,这是因为url中没有安全的办法指定字符集(rfc2396);3)保留字符,url语法中用到的字符,$&+,/:;=?4)不安全字符:空格#%I,出于各种原因;url encode采用%XX方式,XX为字符的十六进制编码。但是在实际应用中,浏览器是否进行url encode,采用何种字符集进行url encode,与浏览器和服务器的设置都有关系,分析如下,以下分析均在windows中文环境中:1,对用户在地址栏中直接输入的url,编码方式与浏览器的设置有关浏览器(模式)PathInfo QueryString Ie(utf-8模式,默认)Utf8编码,无url encode Gbk编码,无urlencode Ie(ansi模式)Gbk编码,无urlencode Gbk编码,无urlencode Firefox(utf8模式)Utf8编码,urlencode Utf8编码,urlencode Firefox(ansi模式,默认)Gbk编码,urlencode Gbk编码,urlencode Opera(utf8模式,默认)Utf8编码,urlencode Utf8编码,urlencode 2,对网页中的链接,与该网页本身的编码方式有关在不改变浏览器默认选项的情况下,各个浏览器的编码方式如下浏览器(网页编码方式)PathInfo QueryString Ie(utf8网页)UTF-8编码、urlencode UTF-8编码、无urlencode Ie(gbk网页)UTF-8编码、urlencode GBK编码、无urlencode Firefox(utf8网页)UTF-8编码、urlencode UTF-8编码、urlencode Firefox(gbk网页)GBK编码、urlencode GBK编码、urlencode 3,对用户提交的数据,不论是get方式还是post方式,其编码方式由网页中的编码方式和相关调用有关。页面的编码方式由http头指定或网页的meta标记指定。http头中含有content-type参数,其中指定了charset:Content-type:text/html;charset=gb2312 Meta标记的方式如下:meta http-eq后台v=content-typecontent=text/html;charset=gb2312/不同的浏览器处理方式也会不同,ie可能通过文件内容识别,firefox偏向meta标签识别。对于传统的表单提交,其编码方式是由页面的编码方式决定的;而ajax提交的数据则与其调用方式有关,如果采用了escape类似的编码函数,则编码成utf-8进行发送。2.2.服务器对编码的处理假设后端均采用gbk存储数据,那么对提交的数据需进行编码识别并进行相应的编码转换,主要针对两种情况:1)url路径部分:由于需要支持中文,这部分是不可控的,取决于操作系统和浏览器,因此需要进行判别到底是什么编码,然后再进行编码转换。2)提交数据部分:提交的数据也既有可能是utf-8编码也有可能是gbk编码。一种办法是判断是否是utf-8编码,但这种判断存在一定的失败率;还有一种办法从页面上控制,提交时强制增加一个字段表示这是否是utf-8编码,apache无需考虑其他的,只根据该字段判断是否需要做utf-8到gbk的编码转化,这个办法是不会出现误伤的。判断是否是utf-8编码有一定的失败率,有如下几种情况:1)判断错误。主要发生在utf8与gbk编码重叠的部分,需根据实际应用进行处理。3)判断成功,但是转换失败。没有对应的gbk编码会导致转换失败,例如韩文字符,在这种情况下可转成实体。4)判断是否是utf-8时判断错误,并且转换失败,这种情况下不会出现问题。编码的识别和转换完成后,后端的模块也需要根据实际应用进行各种各样的处理,如:控制字符过滤、繁简转换、全半角转换、半个汉字处理、字符集过滤等等。当获取到数据组装将要返回的页面时,对出现在页面上的信息需进行一定的转义,比如对于一些由html标签组成的文本,如果不进行特殊处理,那么浏览器会当做标签来进行解析,从而引起页面展现错误。3.编码问题分类3.1.gbk字符集中的特殊字符1)0x80欧元符号【分析】数据库支持有问题,会自动截断;gbk对其编码与其他编码方式不兼容。非必要条件下建议过滤掉。【Bad case】我们在进行编码设计时将包含欧元符号的信息插入数据库,因为数据库将欧元符号以后的部分截断,记录的信息的长度与实际长度不一致从而引起下游模块的逻辑错误。2)0x00-0x31控制字符部分【分析】控制字符无法打印。【bad case】当用户构造了由控制字符组成的信息,这部分信息显示在页面上,会使页面上本应出现文字的地方出现空白,并且如果这部分文字存在链接会使得链接失效从而导致不可点击。3)0x7F空白区位【分析】如果输入会是不可见字符,建议过滤掉。4)0x5C反斜杠【分析】它的特殊性在于两个原因:1、它作为转义符标示的特殊用法;2、它编码区间落在GBK字符集的后半个汉字允许的编码区间内。由于这两个原因,再结合GBK字符集本身存在雪崩问题的隐患,当末尾存在半个汉字,和0x5C字符结合就可能导致转义符号无效,裸露出后续的等,导致转义符号实效,带来一些安全问题和js失效等问题。或者和半个汉字结合导致mysql转义处理失效。5)空洞区:0xd7fa-0xd7fe,0x817f-0xa07f,0xaa7f-0xfe7f【分析】GBK前半个汉字的范围在0x81-0xfe之间,不含0xff,如果用户构造了0xff这样的半个汉字上来,由于部分浏览器支持的问题,例如ie,就会把0xFF字符当作GBK的前半个汉字和后续字符结合。除此之外,码区的中间也有一些空洞【bad case】如果黑客构造0xff 0x5c 0x27这样的字符串(0x5C是,作为转义标示符号,0x27是单引号),那么0xff和0x5c结合成为一个不可见字符,导致原本的转义失效,暴露出来造成安全漏洞。6)Sql语句中的特殊字符:、分析mysql对于特殊字符如等需要处理后才能存储,采用的函数是mysql_real_escape(),将其中的特殊字符转义成/*,对这个函数的要求是页面必须存在一个可用的mysql连接。7)字符外形和全角英文字符完全一致的字符:0xA6A2与0xA7A2,0xA976与0xA3A8 8)全角空格:0xA1A1 9)扩展汉字区域:主要是非汉字区域和特殊字符10)Cp936和其它码表定义不一致的地方11)GBK编码中和其他编码方式有冲突或者有处理方式不一样的个别字符12)可以构成强制转义字符的字符: )字符串结束符:message 14)可能被作为数据结构分隔符的字符15)边界字符:丂(0x8140),亐(0x8180),侩(0x837E),凗(0x83FE),狛(0xA0FE),癄(0XAFA0),(0xFE7E),鳌(0xF7A1),(0XFEA0),齄(0XF7FE)。16)Trailing byte在low-ansi范围中(4个例子)腀(0xC440/0x8140)儬(0x83A0/0x512c)爘(0xA07C/0x7218)爢(0xA086/0x7222)17)Leading和trailing byte大小写是相同的表示(3个例子)C/c丆(0x8143)/乧(0x8163)M/m鳖(0xF74D)/鱩(0xF76D)S/sS(0XA053)/s(0XA073)18)Trailing byte和Leading byte范围相同(4个例子)亖(0x8181)汉(0xBABA)牋(0xA0A0)鼢(0xF7F7)19)leading或trailing byte是0xAA,0xAE or 0xBF,容易变成乱码(3个例子)煪(0x9FAA)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论