关于字符集,和乱码的思考,

原创

导读:只要,文本内容的,编码方式与终端的编码,方式一致(或兼容),则一定不会★出现☆chū xiàn★乱码。从,现象上来看,当从一个,ansi编码,的文本中拷贝★中文☆zhōng wén★字符,再到utf-8编码,的文本中进行粘贴,没有★出现☆chū xiàn★乱码,★但是☆dàn shì★,这两种,编码方式,是不同的,也就是说,必然在,这个过程中出现,了编码,转换,个人怀疑是利用,剪贴板进行,复制的★时候☆shí hou★,进,行了编码,转换,将,复制,的文本保,存为操作系统内码,然后粘贴的★时候☆shí hou★由应用程序进行,内码到utf-8编码,的转换,完成粘贴。

唯美的风景图片,就算不能在一起dj,麻鹰,成都卖菜哥,属牛的几月出生最好,新世纪的德鲁伊,夺宝联盟下载,g700 华为,轻关易道 通商宽农,年历壁纸,。

关于字符集和乱码的,思考 2011-12-12 16:05:58 分类: Delphi ★重要☆important★,★提示☆tips★:本文并非学术文章,本人也并非语言和文字学领域人士,只是出于,好奇心,根据,★自己☆his★的理解,写下这篇,文章。本文的参考文档都来源于互联网,★而且☆but★并未一一,考证其准确性,和,权威性,★因此☆therefore★,本文仅供参考。,     字符集和,字符编码的,★问题☆foul-ups★一直,困扰着我,之间曾经,多次,尝试,把这个★问题☆foul-ups★理解清楚,但始终★由于☆Meanwhile★有些,细节,问题★无法☆to be★,自圆其说因而放弃。网上的,资料,多数描述过于,简单,又或者,作者,本人对问题也了解,不深入,容易产生误导。最近我终于下定决心,将之前,对“乱码”问题的思考更进一步,否则将始终是一丝遗憾。这里,也不得不,★感☆sense★叹,老外的“科普,”做的好啊,网上有很多,质量,相当高的文章,表述严密,引用充分,例证丰富,我,★相信☆上帝会存在的★,在国内各,领域的专家,也不少,计算机,和语言学方面,都有很多有建树的,大,牛,★也许☆Perhaps★是,太忙吧。对我个人而言,最★重要☆important★的一片文章,是“Charactet set encoding basics”,在本文最后,有链接的地址,本,人的,翻译,版本在这里:http://blog.chinaunix.net/space.php?uid=11187&do=blog&id=3034493 1.字符集,的基本概念,什么是字符集?什么是字符编码?按照,“Charactet set encoding basics”,文中的定义,字符集的编码,模型分为,以下,4个,层次1)抽象字符清单Abstract charactet repertoire (ACR),无序,无编码;2)已编码,字符集Coded charactet set (,CCS),有序,有,编码;3)字符编码★规则☆regulations★Charactet encoding form (CEF),有序,有编码;4)字符编码方案Charactet encoding scheme (CES),有序,有编码,有,传输和储存★规则☆regulations★(字节序,);这种分层方式,比较偏于学术化,不太容易理解。,按我个人的理解,GB2312/GBK/GB18030/ASCII,★这些☆These★字符集编码规则,★由于☆Meanwhile★都基于8-bit字节,是属于,前三层的,★可以☆can★认为是三层合一,。如果,拿,Unicode来说明的话,Unicode中定义,的★所有☆all★字符的集合,是第一层;★我们☆we★通常说的,Unicode编码,是指的第二层;现在最,★常见☆Common★,的UTF-8,是指的第,三层,。当UCS-4在以,8-bit为基础的计算机中,存储和,传输时,就要涉及,字节序的问题,就是第四层,分为big-endian和little-endian。, 借用“,程序员,趣味读物:谈谈Unicode编码”,中举,的一个,记事本,例子,(内容不同):1)打开记事本(windows自带的那个),输入,“我”;2)另存为, 我_ansi.txt,★注意☆危险信号★,编码,选择“ANSI,”;3),另存为 我,_unicode.txt,★注意☆危险信号★,编码选择“Unicode”;4)另存为 我,_unicode_big.txt,注意,编码选择“Unicode Big Endian”;5),另存为 我_utf8.txt,注意,编码选择,“UTF-8”;保存完以后,看一下,4个,文件的大小,很有意思吧,分,别是2/4/4/6个,字节,再用二进制方式(推荐使用,ultraedit),查看一下其中的内容:(高位,字节在前,)1),ansi:CE, D22)unicode:FF, FE 11 623)unicode_big:FE FF 62 114)UTF-8:EF BB BF E6 88 91第一个,文件,ansi,比,较好解释,2字节,就是GB2312/GBK/GB18030编码,即简体★中文☆Chinese★windows的默认内码第二个文件,unicode,就是,Unicode编码,“,我”的编码,是,0x62 0x11,不过前面多了2字节的前导符,FF FE,表示为little-endian第,三个,文件,unicode_big,也是,Unicode编码,不过前导符变为FE FF,表示big-endian第四个文件,UTF-8,是在Unicode基础上,的二次,编码,分别将FE FF(big-endian)和62 11进行了,二次编码,详细,编码过程参见“程序员趣味读物,:谈谈Unicode编码,”  ★常见☆Common★字符集(字符编码规则)ASCII,读作阿斯克码,7bit表示,美国,国家标准信息编码,是最常用,★英文☆English★,字母和,符号,数字的集合及编码;它的常见,别名是,ISO 8859-1 Latin1EASCII,扩展ASCII,码,完整的利用一个字节,在,ASCII的基础上扩展了★一些☆some★,不常用,字符,GB2312,国标★中文☆Chinese★字符,编码,1980年制定并颁布;GBK,国标码,1995年GB18030,国标码,2000年以上这三个编码标准,★都是☆All are★向下兼容,的,兼容的,意思有两方面,其一是指字符的集合,其二,是指编码。另外,在微软操作系统中(其实也,★影响☆effect★到了,Linux领域),经常★出现☆There★“代码页,”(code page)的概念,★这些☆These★代码页,只是微软★自己☆his★的定义,★可以☆can★理解为CP936=GBK。Unicode,UTF-8,我原来,一直以为这,两个东东是一回事,后来发现其实,理解,★错了☆Designers★,UTF-8可以理解为是以,Unicode为基础进行二次编码,的,详见这篇文章:“程序员趣味,读物:谈谈Unicode编码”,http://pcedu.pconline.com.cn/empoldet/gj/othet/0505/616631_1.html  2.关于乱码的,思考什么,是,乱码个人认为,如果在,储存或传输,过程中,计算机中的信息,不能被正常解析,从而导致,在信息★展示☆showed★,的★时候☆When★★出现☆There★★无法☆to be★,被正确理解,的情况,可以认为出现了“,乱码,”。常见的,乱码有两种★表现☆performance★★形式☆form★: 1)部分,中文字符能够正常★展示☆showed★,另外的中文字符,被展示为方框;       这种情况,多数是由于缺少相应的★字体☆Typeface★,★支持☆support★,例如,在虚拟,机上安装完,linux之后,如果没有安装,图形界面,默认的字符,窗口其实是,没有相应的★字体☆Typeface★★支持☆support★的,这时,的中文★只能☆can only★,显示为方框,安装zhcon以后才能够,正常,展示GBK/UTF8的,中文字符。,       还,有一个场景,部分网页上的字符,并不,能被★所有☆all★浏览器支持,或者,该浏览器对,某种编码,方式的支持不,完整,会出现,部分,字符展示为,方框,的情况,。       另外,如果能够,以GBK/GB2312正常展示的网页,如果手工,将encoding变更为,utf-8,则,所有中文,字符,都会变成方框。, 2)★几乎☆much★,所有字符都不能正常展示,★许多☆many★字符,被显示为“?”,或者被显示为一大堆,不可理解,的古怪字符;       这种情况,很★可能☆would★是,由于字符编码不配套,需要具体分析。例如,在浏览器,中能够正常显示的,页面,如果将其编码更,改为★其他☆other★不兼容的编码,则,很多会展示为“?”和,乱七八糟字符的,组合 乱码,产生的原因产生乱码的原因,很复杂,也正是这个原因导致了对,乱码问题的分析很难全面和彻底,。★但是☆But★,综合我目前遇到的乱码问题来看,只要将,字符,展示的过程剖析清楚,一段段的,调整,总能找到★解决☆settle★的办法。 字符在计算,机中,★都是☆All are★以二进制的方式进行存储,的,★而且☆but★文本本身是不能够,标识它使,用的编码,方式的。也就是说,同一段二进制字,节流,可,以用很多种不同的编码方式去,解码,然后根据解码后的,结果,(也是,二进制字节流),在操作系统中,按照预,定义好的,字体进行展示。所谓字体库,或者,字库,其实,就是,数字,和相应展示方式(点阵,truetype等)的组合。计算机本身是不会,“体会”到“乱码”的,★发生☆occasionally occurred★的,它只是按照用户选,定的字体,根据不同,的数字进行展示,而已,无论,展示,的,结果★如何☆how★,都只有★人才☆牛B人物★能,判断,“乱码,”与否。乱码的,产生,其实只有两个原因,一是没有使用,正确的解码规则来,解释字,节流,二是使用了错误的展示,字体。实际应用当中,编码规则的问题居多。 单,字节的,编码通常,情况下不会出现乱码的问题,特别是,★英文☆English★字符,而双字节由于多数,情况下编码规则复杂,另外存在中间,截断的,问题,会比较复杂。从产生问,题的渠道来看,常见的有以下,几类,: 1),网页展示乱码    多数,情况下,可以通过更改页面编码方式,来★解决☆settle★。少数情况下,浏览器本身处理多语言,字符集有缺陷的,★时候☆When★,无论怎样修改编码,方式,都不能彻底解决乱码问题。,例如,截至本文,定稿,IE9就存在部分UTF-8中文编码,无法解析,的,问题,同样的网页在Chrome和firefox中,都没有问题,。 2),UNIX/LINUX终端,显示乱码2.1)终端,的中文,环境;    如果没有合适的中文环境(,字库,支持),无论解码方式★如何☆how★,正确,也不★可能☆would★,正常展示,中文。在常,用的终端工具中,例如,:Xshell/Secure CRT/Putty,都可以设置终端的字符编,解码方式,通常设置的值有两个系列:    其一,GB2312/GBK/GB18030/CP936/ANSI/Default等,其实都是兼容的编码,或者仅仅是名称不一样;    其二,UTF-8,这个是在互联网上最,常见的,编解码方式了;    另外,如果不是windows下,的,终端工具,而是系统,自身,的字符终端,则,可以,安装字符终端专用的中文环境,例如linux下的,zhcon 2.2),cat显示文本文档内容,    通过类似cat★命令☆orders★,的方式显示纯,文本文档的,内容,通常只受,一个因素的★影响☆effect★,即终端,的工具的字符编码方式,常用工具,中,都可以进行设置,。只要,文本内容,的编码方式,与终端的编码,方式一致(或兼容),则,一定不会出现乱码。 2.3)★命令☆orders★行的中文★提示☆tips★(CLI)    命令行接口Command Line Interface的,提示,语言,是通过环境变量进行设置的,好几个变量都可以设置,但优先级,有区别,其中LC,_ALL > LC,_XX, > LANG,如果想用,中文显示提示信息,可以★这样☆then★设置:    export LC,_ALL=zh_CN.gbk     其中zh表示使用,中文,输出,提示信息,gbk表示使用GBK编码方式输出中文提示信息,这个编码方式,要与终端的设置一致,或者兼容才,可以,正常,显示; 2.4)输入中文信息    从,Shell环境输入中文,与vi/vim这种编辑器的情况稍有不同,编辑器的情况,放,到下一节,说明,。按照一般的理解(,我原来就是★这样☆then★理解的),只要能,正常显示中文的地方,一定能够,正常输入中文。,★但是☆But★,实测,的情况略有不同,详见,下面的表格。,    输入中文信息,我暂时只,考虑,了,以下,三种情况:    a),在,SHELL命令,行中输入中文           这种场景下,如果,终端字符集,是GBK,LC,_ALL为,UTF-8时,输入的,中文字节流乱序(第一个,中文字符的高,字节被,放到字节流的末尾),无法正常展示。,    b)使用cat等方式输入,中文,并重定向到文件中,           这种,场景下,任何时候,都能够正常输入,中文    c),使用文本编辑器,详见下一节描述,    与仅仅显示,中文信息不同,输入中文,的时候实际上经历了,更多的步骤。最★开始☆appeared★,从终端,工具中输入中文编码字节流,然后经过网络,协议传输到★服务☆services★,端,★服务☆services★端★收到☆received★,字,节流以后,根据终端,设置的情况,再推送,显示信息,到终端工具,终端工具进行呈现。在SHELL命令,行中输入,中文不正常的情况,很有可能是由于服务端,的处理逻辑不健全。 2.5)文本编辑器,例如,vim    文本编辑器的种类很多,emacs/vi等,vi的版本也,很多,各个★主流☆mainstream★,UNIX,平台的商业版本,实现都不相同,还有vim。本文暂以vim为例子,进行说明,★其他☆other★编辑器的,情况,★应该☆yīng gāi★是类,似的,。可以参考,:“让vim★认识☆known★,更多的编码”,http://blog.chinaunix.net/space.php?uid=20147410&do=blog&id=3018800。     遗憾的是,这篇文章并未给出,vim处理这三个内部变量的顺序,经摸索,顺序★应该☆yīng gāi★,为,:    1)fileencoding    2)endocing    3)termencoding    这三个内部变量均,可以通过set xxx=xxx的,方式进行,设置,并可以通过,set和set all进行,查看。另外,上面提到,的博文中,是使用,LANG变量来改变vim的encoding变量值,但由于LANG的优先级,最低,实际使用,过程中,使用LC_ALL的效果,最好,当然其实也可以直,接在vim中,使用set进行,设置。     个人理解,如果仅仅从输入,和,输出,(显示,),的角★度☆attitudes★,来看,其实vim等文本,编辑工具并没有必要设置,3个,不同,的变量来,进行处理,这,大概,也是★大多数☆most★商用,unix平台的vi版本,都,没有,类似设置的原因,。提供3个变量的原因在于,vim试图提供★一些☆some★编码转换,的方式,例如,通过设置fileencoding变量,可以改变vim写入和,读出使用的编码,而termencoding仅仅,改变,显示时使用的编码方式,而encoding其实,只是提供缓冲。这与数据库的字符集(编码)处理方式,是类似的。也可以这样理解,无论这三个变量,设置为何值,其实并,不见得不会影响数据的,输入,和展示。例如,在★我们☆we★输入输出,中文信息的时候,即便fileencoding=encoding=termencoding=iso8859(,英文,字符集),只要,文本文件的,编码方式与,终端的,编码方式一致(兼容),比如,都是GB2312,文本信息,都可以正常,展示和输入。 附表:不同设置,情况下的中文显示,结果服务,端环境:ubuntu 11.10 服务器,版★客户☆customer base★端环境,:中文,win7+Xshell 4 文件编码终端,字符集,LC,_ALLcat输出SHELL输入VIM相关备注vim显示vim输入encodingfileencodingtermencodingGBKGBKGBK正常,正常,正常正常GBKGBKUTF-8GBKGBK乱码正常正常,GBKUTF-8GBKUTF-8GBK乱码,正常乱码乱码GBK如果将encoding或termencoding改为utf-8,则可以正常,显示,UTF-8UTF-8GBK正常乱码乱码GBKUTF-8如果将,encoding或,termencoding改为utf-8,则,可以正常,显示GBKGBKUTF-8正常乱码,乱码,乱码UTF-8latin1如果将encoding或termencoding改为latin1,则可以正常,显示;或者,将encoding和fileencoding改为GBK(,cp936)UTF-8GBKUTF-8乱码,乱码,乱码UTF-8utf-8如果将encoding或termencoding改为cp936,则可以正常显示,GBKUTF-8UTF-8乱码正常乱码乱码UTF-8latin1如果,将fileencoding改为cp936,则可以,正常显示UTF-8UTF-8UTF-8正常正常正常UTF-8   3)数据库乱码    数据库中与,编码/字符集相关的设置主,要有两个,一个是数据库本身,的,编码,另一个是★客户☆customer base★端,环境的编码。网上有很多关于数据库乱码问,题的,★讨论☆discussion★,多数并没有涉,及到问题的,本质。,数据库中保存的数据,其实,与,文件方式保存,的数据,没有,什么两样,都,只是字节流而已,而,字节流,本身通常是不能自我标识的,例如,如果仅仅,根据,二进制的编码,无法判断出它的,内容是采用,GB2312编码,还是EASCII,编码,或者是一个图像信息。,★也许☆Perhaps★,正是由于字节流无法,标识自己,★因此☆therefore★,需要有一个参数来标识数据库,使,用的,文字,编码,。,在客户端与服务端,的编码,设置统一的,时候,无论在数据库的字段中存储什么样的,数据,都是,不影响数据,的储存和,展示的,原因,是,不会★发生☆occasionally occurred★编码转换。     例如,网上,很多帖子,★讨论☆discussion★到乱码,问题的时候,给出的★建议☆pointers★都是,将数据库的,字符集设置为utf-8,这当然不会有什么,问题,utf-8编码,是被最广泛使用的编码标准,所以,支持,也相当,完备,特别是utf-8编码★几乎☆much★可以被所有软件“识别”出来(特征码)。这样一来,实际上掩盖了编码的,问题,。,其实,如果仅仅为了储存和展示中文信息,将数据库的字符集设置,为iso-8859-1(单字节)编码,客户端的语言,环境也设置为同样的编码方式,存取,中文数据,也,不会有,任何,乱码的情况发生,。之所以产生乱码,是,由于在★某些☆Some★地方,出现了编码,方式,的不匹配。     比如,数据库的编码设置为GBK,但是,客户端,的设置为UTF-8,那么,如果在客户端使用,UTF-8的编码方式输入中文数据,当客户端,软件,发现这种不一致时,会执行从UTF-8到,GBK的编码转换,然后通过网络插入到,数据库的具体,字段,中。当这段,数据被读取时,如果客户端的设置,为,UTF-8,那么,同样要,发生GBK,到,UTF-8的转换,最终,以,UTF-8的,★形式☆form★展示数据,。但是,如果数据被,读取时,客户端的设置为,GBK,则数据无需,转换就可以,以GBK的,形式直接呈现,★然而☆however★,如果客户端是设置为UTF-8编码的网页,但使用GBK方式★访问☆visit★,数据库,那么数据被最终呈,现时就会出现乱码。     总之,数据库提供设置数据库和客户端编码,方式的选项,只是,为了,更好的提供编码,转换,★工作☆work★,并不是,必需的,无论设置成何种,编码方式,与实际存储在字段,中的数据都没有必然★联系☆links★,只是会在编码转换的时候提供方便,否则,这些,转换★工作☆work★就★只能☆can only★,★完全☆completely★,交给客户端来完成。, 3.尚未解决的疑问 1)关于,windows剪贴板的实现机制中,是否,★包括☆included★了编码转换  从现象上来看,当,从一个ansi编码的,文本中,拷贝中文字符,再到utf-8编码,的,文本,中,进行粘贴,没有出现,乱码,但是这两种,编码方式是不同,的,也就是说,必然在这个过程中出现了编码转换,个人怀疑是利用剪贴板进行复制的时候,进行了编码,转换,将复制的文本保存为操作系统内码,然后粘贴的时候,由,应用程序进行,内码到utf-8编码的转换,完成粘贴。 2),输入法输入,不同编码的文本时,采取什么机制?,  当打开,一个cp936编码的,文件进行编辑时,输入法的输出是cp936编码的,但,打开一个utf-8编码,文件进行编辑时,输入法的输出变成了utf-8的,输入法是如何,★知道☆knew★,什么时候,应该,使用什么编码的?个人,猜想,有可能输入法的输出只是操作系统,的,内码,在文本编辑器,中进行内码到其他编码的,转换。,

关于字符集,和乱码的思考,
评论:

打鱼1000炮伊利金领冠官方,。关于字符集,和乱码的思考,

魔兽世界官网打不开,博士后招聘启事,人生梦想,msn停用,六一班,不敌,劝退师收费百万,天堂电影 迅雷下载,佛科院,。断掌好不好,慢摇网,塔拉星球之战下载,华声在线,kappa.mp4,梦见车祸,。

关于字符集,和乱码的思考,
评论:

打鱼1000炮28岁副镇长辞职,。关于字符集,和乱码的思考,

九布人体摄影,狡猾的风水相师,十二属相婚配秘笈,忘情酒吧,小清新桌面壁纸,炼鬼修仙,大明首辅,n980,石家庄二手电脑配件,。星座速配,慢摇,田馥甄男友,京华友好,马唯中照片,英文情书,蹲墙角吃面照走红,。

关于字符集,和乱码的思考,
评论:

澳门亚洲城赌场水瓶座开运水晶,。关于字符集,和乱码的思考,

台湾联合报,谣传六小龄童死讯,农产品打一成语,哈哈镜打一成语,大信会计师,起点论坛,上海短期贷款,何以笙箫默免费阅读,平山蓝里,松溪论坛,。曾祥宝,中国城dj,东莞性都,巩俐资料,赞美母亲的歌曲,隋末之乱臣贼子,尚德 破产,17k网站,星座开运水晶,dnf机械师加点,。