asfman
android developer
posts - 90,  comments - 213,  trackbacks - 0
关于编码、unicode、utf-8的讨论

不知道你有没有这样的感受:为什么PHP很少有乱码问题而用Java做WEB应用却这么麻烦呢?为什么在Google上能用简体中文查到繁体中文,甚至日文的结果?而且用Google的时候发现它居然能自动根据我使用浏览器的语言选择自动调出中文界面?

很多国际化应用的让我理解了这么一个道理:Unicode是为更方便的做国际化应用设计的,而Java核心的字符是基于UNICODE的,这一机制为应用提供了对中文“字”的控制(而不是字节)。但如果不仔细理解其中的规范,这种自由反而会成为累赘,从而导致更多的乱码问题
======================
什么是编码页(code page)?
  正如我们所知,计算机只懂得数值。因此,当我们想要它处理文本时,就把一门语言中每个字符都赋以特定的值。简单地说来,这种字符与数值的对照表就叫编码页。在这种情况下,你可能常会听到诸如字符集(charset),字符表(charmap),编码(encoding),编码字符集(coded character set)等术语。虽然彼此间还有一些细微的差异,为理解的目的你可以认为它们都是指每种语言的字符、数值映射表。ASCII编码页就是一个很著名的例子,它把英文字母表和一些控制字符映射到一些特定的数值上去。


还有哪些编码页?围绕着编码页有哪些问题?
  ASCII编码映射了127个字符,因此7位(bit)二进制数足够用来表示127个字符。程序则典型地在8位的缓冲区内处理文本。这在处理其它的语言的编码页是会出问题。例如日语这种语言,有成千让万个字符,8位二制只能表示256个不同的字符,不可能唯一地表示每一个日语字符。因此,人们用几个字节来表示一个日语字符。现在,我们又遇到另一个问题。缓冲区的字节数不等于缓冲区中的字符数。每一个简单地字符串操作,都需要将字节组装成字符。
  认识到这种复杂性,开发人员利用一种叫宽字符(wide-character)的技术来处理外语字符串。宽字符基本上是16位或32位的数据类型。容量够大,能满足亚洲语言的需求。处理字符串不再使用8位的缓冲区(char *),而是使用16位的缓冲(unsigned short *)。因此每次移动指针,你都可以保证跳过了一个字符(而不是原先那可能是半个)。
  不同的开发商使用不同的编码页,给这带来了混乱。也就是说,同一个日语字符,在一个机器上可能用0x95和0x5c两个字节表示,而在另外的机器的上则可能是0xc9和0xbd。这样一事每次交换数据都要进行一次转换(称为码表转换(charmap conversion)或码集转换(codeset conversion))。

什么是Unicode?它是如何解决这个问题的?
  每一种语言的不同的编码页,增加了那些需要支持不同语言的软件的复杂度。因而人们制定了一个世界标准,叫做unicode(http://www.unicode.org).Unicode为每个字符提供了唯一的特定数值,不论在什么平台上、不论在什么软件中,也不论什么语言。也就是说,它世界上使用的所有字符都列出来,并给每一个字符一个唯一特定数值。

什么是UTF-8?它与UNICODE是一回事吗?
  Unicode的最初目标,是用1个16位的编码来为超过65000字符提供映射。但这还不够,它不能覆盖全部历史上的文字,也不能解决传输的问题(implantation head-ache's),尤其在那些基于网络的应用中。已有的软件必须做大量的工作来程序16位的数据。
  因此,Unicode用一些基本的保留字符制定了三套编码方式。它们分别是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列来编码的,用一个或几个字节来表示一个字符。这种方式的最大好处,是UTF-8保留了ASCII字符的编码做为它的一部分,例如,在UTF-8和ASCII中,“A”的编码都是0x41.
  UTF-16和UTF-32分别是Unicode的16位和32位编码方式。考虑到最初的目的,通常说的Unicode就是指UTF-16。在讨论Unicode时,搞清楚哪种编码方式非常重要。Unicdoe相关的技术介绍参见http://www.unicode.org/unicode/standard/principles.html.

===============
话说这个VB6,很是无耻,居然内置了支持Unicode的功能,也就是说,当你读入一个字符串时,它根据本地缺省语言的对应关系将之转换为Unicode,输出时,再从Unicode转换为本地编码。一方面,它当然方便啦,随便出个什么语言的版本都好方便的,而且在Unicode的系统上,如NT,那它可就如鱼得水,Unicode毕竟是软件发展的方向,像现在中文Win9X使用的GBK内码,实际上就是向着Unicode走了一大步。可是在另一方面,这种支持实际上极大地延缓了字符串的处理时间!想想看,如果我们从文件里读一行并显示,本来是很简单的事情,可是在VB6里面,实际上多了一段转换到Unicode的时间,如果我们用字符串从原文件里读一行,然后分析,再写到目的文件里去,实际上就多了两重的时间(本地到Unicode,unicode到本地)。当然对于这种小事,高手们想必也都有处理的办法(如用byte数组来代替字符串)
说了这么一大堆Unicode的坏话,还没说到正题呢,由于VB6内置对Unicode的支持,而Unicode里面分别和 GBK 以及Big5汉字都有对应关系,所以要实现转换也只是一件小事,下面我们就有请本次女主角出场。(哗哗哗哗……掌声不绝。)
函数strConv! 这个美眉大家可能在VB5里面也都见过的,她有一些保镖,可以帮她把字符串在Unicode和本地编码之间转换,而在VB6里面呢,strConv又多了一个保镖!大家请仔细看:
strConv(string,conversion) `VB5
StrConv(string,conversion,LCID) `VB6
===============
  Java内核是unicode的,就连class文件也是,但是很多媒体,包括文件/流的保存方式
  是使用字节流的。 因此Java要对这些字节流经行转化。char是unicode的,而byte是字节.
  Java中byte/char互转的函数在sun.io的包中间有。其中ByteToCharConverter类是中调度,
  可以用来告诉你,你用的Convertor。其中两个很常用的静态函数是
   public static ByteToCharConverter getDefault() ;
   public static ByteToCharConverter getConverter(String encoding);
  如果你不指定converter,则系统会自动使用当前的Encoding,GB平台上用GBK,EN平台上用
  8859_1
  
  我们来就一个简单的例子:
     "你"的gb码是:0xC4E3 ,unicode是0x4F60
     你用:
     --encoding="gb2312";
     --byte b[]={(byte)"u00c4",(byte)"u00E3"};
     --convertor=ByteToCharConverter.getConverter(encoding);
     --char [] c=converter.convertAll(b);
     --for(int i=0;i0xC4,0x00E3->0xE3,因此0xC4,0xE3被放进了
1.网页传参数不提倡用get方法,而且用户可以调整是否用utf-8发送 /////////// 这一行要注意了
2.建议jsp中最好不要用,实际上加不加这句都有实现中文正常显示的方案,我认为不加方便些,至少不用写这些代码,如下的配置我认为可以使中文正常显示:
a.所有的javabean用iso8859-1编译
b.jsp文件中不要写以上charset=gb2312的语句(写了反而错)

这段更重要了,做后台sql的都看看吧

我们的目标是,任一国家的客户端通过Form向Server发送信息,Server把信息存入数据库中,客户端在检索时仍然能够看到自己发送的正确信息。事实上,我们要保证,最终Server中的SQL语句中保存的时包含客户端发送文字的正确Unicode编码;DBC与数据库通讯时采用的编码方式能包含客户端发送的文字信息,事实上,最好让JDBC直接使用UNICODE/UTF8与数据库通讯!这样就可以确保不会丢失信息;Server向客户端发送的信息时也要采用不丢失信息的编码方式,也可以是Unicode/Utf8。
  如果不指定Form的Enctype属性,Form将把输入的内容依照当前页面的编码字符集urlencode之后再提交,服务器端得到是urlencoding的字符串。编码后得到的urlencoding字符串是与页面的编码相关的,如gb2312编码的页面提交"中文测试",得到的是"%D6%D0%CE%C4%B2%E2%CA%D4",每个"%"后跟的是16进制的字符串;而在UTF8编码时得到的却是"%E4%B8%AD%E6%96%87%E6%B5%8B%E8%AF%95",因为GB2312编码中一个汉字是16位的,而UTF8中一个汉字却是24位的。中日韩三国的ie4以上浏览器均支持UTF8编码,这种方案肯定包涵了这三国语言,所以我们如果让Html页面使用UTF8编码那么将至少可以支持这三国语言。
  但是,如果我们html/Jsp页面使用UTF8编码,因为应用程序服务器可能不知道这种情况,因为如果浏览器发送的信息不包含charset信息,至多Server知道读到Accept-Language请求投标,我们知道仅靠这个投标是不能获知浏览器所采用编码的,所以应用程序服务器不能正确解析提交的内容,为什么?因为Java中的所有字符串都是Unicode16位编码的,HttpServletRequest.request(String)的功能就是把客户端提交的Urlencode编码的信息转为Unicode字符串,有些Server只能认为客户端的编码和Server平台相同,简单地使用URLDecoder.decode(String)方法直接解码,如果客户端编码恰好和Server相同,那么就可以得到正确地字符串,否则,如果提交地字符串中包含了当地字符,那么将会导致垃圾信息。
posted on 2006-07-20 14:21 汪杰 阅读(3527) 评论(4)  编辑 收藏 引用

FeedBack:
# re: 关于编码、unicode、utf-8的讨论
2006-07-20 14:22 | 汪杰
ASCII: 发音为: as'-kee。美国信息交换标准码(ASCII),小型计算机最常用的编码方法,用于将字母、数字、标点符号以及控制码转换成数字形式 一旦定义后,其他计算机和通信设备就可以识别和看懂ASCII字符。ASCII定义了128个字符,包括α字符、数字、标点符号或信号,使用7个0/1位和1个奇偶位(用于数字)。 例如“C”表示为1000011,而“3”表示为0110011。作为一个7位代码,且每一位只能是“0”或“1”,因此ASCII可以描述128种“事物”,即2 x 2 x 2 x 2 x 2 x 2 x 2=128。ASCII是一种代码,事实上包括IBM、Apple以及Radio Shack/Tandy在内的世界上的每一台个人电脑都在使用这种代码对“事物”进行编码。实际上,如果个人电脑都使用了兼容调制解调器或者是空调制解调器电缆且收发速率相同,那么该兼容性编码就可以(由美国国家标准协会ANSI开发)实现个人电脑之间的通话。ASCII有各种不同类型。(没有什么是完全标准的了。)最重要的一种类型(最早来自IBM的)称为ASCII扩展。ASCII扩展将字符转换为8位代码(或1个字节),并使用前127个字符代码表示外语字母以及其他有用的符号如那些画正方形的符号。但是127以及127以下,扩展的8位ASCII代码相当于标准7位ASCII代码。ITU(现在称ITU-T)称ASCII为国际5号电报字母表。

EBCDIC:EBCDIC如同 ASCII 一样 有特定的符号 是由IBM提出的。EBCDIC(发音为ebb'-si-dick),大量应用于IBM和IBM兼容大型计算机(但是不包括使用ASCII以及ASCII扩展的个人电脑)。EBCDIC是一种8位编码方案,也就是最多有256种“事物”进行编码,即2 x 2 x 2 x 2 x 2 x 2 x 2 x 2 = 256。EBCDIC对字母、字符以及标点符号的编码与ASCII完全不一样。对于需要由IBM大型机(使用EBCDIC编码)阅读的 ASCII文件,必须使用众多翻译程序中的一个将ASCII文件转换成EBCDIC代码才能供IBM大型机阅读。
OEM:OEM是英文Original Equipment Manufacturer的缩写,按照字面意思,应翻译成原始设备制造商,指一家厂家根据另一家厂商的要求,为其生产产品和产品配件,亦称为定牌生产或授权贴牌生产。即可代表外委加工,也可代表转包合同加工。国内习惯称为协作生产、三来加工,俗称加工贸易。

UTF -8、unicode:每一种语言的不同的编码页,增加了那些需要支持不同语言的软件的复杂度。因而人们制定了一个世界标准,叫做unicode(http://www.unicode.org).Unicode为每个字符提供了唯一的特定数值,不论在什么平台上、不论在什么软件中,也不论什么语言。也就是说,它世界上使用的所有字符都列出来,并给每一个字符一个唯一特定数值。
什么是UTF-8?它与UNICODE是一回事吗?
  Unicode的最初目标,是用1个16位的编码来为超过65000字符提供映射。但这还不够,它不能覆盖全部历史上的文字,也不能解决传输的问题 (implantation head-ache's),尤其在那些基于网络的应用中。已有的软件必须做大量的工作来程序16位的数据。
  因此,Unicode用一些基本的保留字符制定了三套编码方式。它们分别是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列来编码的,用一个或几个字节来表示一个字符。这种方式的最大好处,是UTF-8保留了ASCII字符的编码做为它的一部分,例如,在UTF-8和ASCII中,“A”的编码都是0x41.
  UTF-16和UTF-32分别是Unicode的16位和32位编码方式。考虑到最初的目的,通常说的Unicode就是指UTF-16。在讨论Unicode时,搞清楚哪种编码方式非常重要。
  回复  更多评论
  
# re: 关于编码、unicode、utf-8的讨论
2006-07-20 14:23 | 汪杰
常用的字符代码是ASCII码,它原来是美国的国家标准,1967年被定为国际标准。ASCII码由8位二进制数组成,其中最高位为较验位,用于传输过程检验数据正确性。其余7位二进制数表示一个字符,共有128种组合。


OEM是Original Equipment Manufacture(原始设备制造商)的缩写,它是指一种"代工生产"方式,其含义是生产者不直接生产产品,而是利用自己掌握的"关键的核心技术",负责设计和开发、控制销售"渠道",具体的加工任务交给别的企业去做的方式。这种方式是在电子产业大量发展起来以后才在世界范围内逐步生成的一种普遍现象,微软、IBM等国际上的主要大企业均采用这种方式。


Unicode学术学会是一个非盈利的组织,是为发展,扩展和推广使用Unicode标准而建立的,Unicode学术学会设立了现代软件产品和标准文本的表示法。学术学会的会员代表了广泛领域的计算机和资讯工业的公司和组织。学术学会只由会员提供资金。Unicode学术学会的会员资格开放给世界上任何支持Unicode标准和希望协助其扩展和执行的组织及个人

  回复  更多评论
  
# re: 关于编码、unicode、utf-8的讨论
2007-08-20 17:08 | 流浪汉
寰瑧鍖椾含 蹇楁効濂ヨ繍钬斺?旇嚧濂ヨ繍浼氩织镒胯?呯敌璇蜂汉镄勪竴灏佷俊
Mon, 13 Aug 2007 21:40:28 +0800
收件人: hhhbetty@yahoo.com.cn
主题: 寰瑧鍖椾含 蹇楁効濂ヨ繍钬斺?旇嚧濂ヨ繍浼氩织镒胯?呯敌璇蜂汉镄勪竴灏佷俊
发件人: noreply@mail.volunteers.beijing2008.cn 添加到地址簿

蹇楁効钥呯殑寰瑧鏄寳浜渶濂界殑鍚岖墖 听

听 听
寰瑧鍖椾含 蹇楁効濂ヨ繍

听 钬斺?斺?斺?旇嚧濂ヨ繍浼氩织镒胯?呯敌璇蜂汉镄勪竴灏佷俊

灏婃暚镄勫ゥ杩愪细蹇楁効钥呯敌璇蜂汉锛?/span> 听
銆?銆?鍦ㄥ寳浜?008骞村ゥ杩愪细寮?骞曞?掕镞朵竴锻ㄥ勾涔嬮台锛岀29灞婂ゥ杩愪细缁勫浼氩织镒胯?呴儴鍚戞偍镊翠互浜插垏镄勯棶鍊欙紝骞跺镇ㄥ叧娉ㄣ?佹敮镌并?佸弬涓庡寳浜ゥ杩愪细銆佹画濂ヤ细绛瑰姙宸ヤ綔琛ㄧず琛峰绩镄勬劅璋紒
銆?銆?鍖椾含濂ヨ繍浼氩织镒胯?呴」鐩惎锷ㄤ互鏉ワ紝鍦ㄧぞ浼氩悇鐣屽拰骞垮ぇ蹇楁効钥呯殑鍏卞悓锷姏涓嬶紝鍚勯」宸ヤ綔杩涘睍椤哄埄銆效舰鎴愪简鍖呮嫭钬滆繋濂ヨ繍钬濆织镒挎湇锷¢」鐩?佸ゥ缁勫鍓嶆湡蹇楁効钥呴」鐩?佽禌浼氩织镒胯?呴」鐩?佸煄甯效织镒胯?呴」鐩?佺ぞ浼氩织镒胯?呴」鐩?佸ゥ杩愪细蹇楁効钥呭伐浣滈仐浜ц浆鍖栭」鐩瓑鍏釜宸ヤ綔椤圭洰鍜屸?滃井绗戝寳浜?濅富棰樻椿锷ㄧ殑濂ヨ繍浼氩织镒胯?呭伐浣沧牸灞?锛屼负骞垮ぇ蹇楁効钥呯敌璇蜂汉鍙备笌濂ヨ繍銆佽础鐚ゥ杩愭惌寤轰简骞块様骞冲彴銆傛埅镊崇洰鍓嶏紝鍖椾含濂ヨ繍浼氥?佹画濂ヤ细璧涗细蹇楁効钥呮姤鍚崭汉鏁板凡绐佺牬56涓囷紝鍖椾含濂ヨ繍浼氩煄甯效织镒胯?呮姤鍚崭汉鏁板凡瓒呰绷27涓囥??br /> 銆?銆?浣滀负涓?鍚嶅织镒胯?呮槸鍏夎嵛镄勩??007骞?链?镞ワ紝鍦ㄥ弬锷犳镙戞椿锷ㄦ椂锛屼腑锲藉浗瀹朵富甯儭阌《稕涓庡织镒胯?呬翰鍒囦氦璋堬紝骞舵彁鍑轰简娈峰垏甯屾湜銆效浗闄呭ゥ濮斾细涓诲腑缃楁牸鍏堢敓璇勪环钬滃织镒胯?呮槸濂ユ滠鍖瑰厕杩愬姩镄勫熀鐭筹紝鏄ゥ杩愪细鐪熸镄勫舰璞〃ぇ浣库?濄?效寳浜ゥ缁勫涓诲腑鍒樻穱涔熸寚鍑衡?滃织镒胯?呯殑寰瑧鏄寳浜渶濂界殑鍚岖墖钬濄?傗?滃悓涓?涓笘鐣岋紝鍚屼竴涓ⅵ鎯斥?濓紝鎴戜滑鐪熻瘹镄勫笇链涙偍缁х画寮樻壃蹇楁効绮剧銆佷紶鎾ゥ杩愮悊蹇碉紝绉瀬鍙备笌蹇楁効链嶅姟娲诲姩锛屽叧娉ㄥ拰鏀寔鍖椾含濂ヨ繍浼氥?佹画濂ヤ细镄勭锷炲伐浣滐紒璁╂垜浠睿鍚屽弬涓庡ゥ杩愩?佸鐚ゥ杩愩?佸睿浜ゥ杩愶紝涓轰妇锷炰竴灞娾?沧湁鐗硅壊銆侀佩姘村钩钬濈殑濂ヨ繍浼氩仛鍑烘柊镄勮础鐚紒
銆?銆?鎴戜滑鐩镐俊锛?008骞达紝蹇楁効钥呯殑寰瑧鏄寳浜渶濂界殑鍚岖墖锛?br /> 銆?銆?鍖椾含娆四繋镇紒

绗?9灞婂ゥ杩愪细缁勫浼氩织镒胯?呴儴
2007骞?链?3镞?/span>


銆?銆?濡傞渶涓庡织镒胯?呮嫑鍕熸満鏋勮繘琛屾矡阃氾紝璇峰彂阃侀偖浠惰呖锛歝vm@bv2008.cn
銆?銆?濡傞渶浜呜В濂ヨ繍浼氩织镒胯?呭伐浣灭殑鐩稿叧淇℃伅锛岃鐧诲綍锛?br /> 銆?銆?濂ョ粍濮斿畼缃戝织镒胯?呴阆掳细http://www.beijing2008.cn/volunteers
銆?銆?蹇楁効鍖椾含缃戠粶淇℃伅骞冲彴锛?a rel="nofollow" target="_blank" href="http://www.bv2008.cn">http://www.bv2008.cn

鐗堟潈镓?链?绗?9灞婂ゥ鏋楀尮鍏奶繍锷ㄤ细缁勭粐濮斿憳浼氩织镒胯?呴儴
  回复  更多评论
  
# re: 关于编码、unicode、utf-8的讨论
2016-01-21 19:08 | 张丹宁
:cache-control,Expires。  回复  更多评论
  
只有注册用户登录后才能发表评论。

<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(15)

随笔分类(1)

随笔档案(90)

文章分类(727)

文章档案(712)

相册

收藏夹

http://blog.csdn.net/prodigynonsense

友情链接

最新随笔

搜索

  •  

积分与排名

  • 积分 - 467486
  • 排名 - 6

最新随笔

最新评论

阅读排行榜

评论排行榜