??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品日本欧美一区二区三区,日韩欧美看国产,一区二区三视频http://www.aygfsteel.com/keweibo/category/25848.htmlAs long as you are there to lead me ,I won't lose my way zh-cnFri, 21 Sep 2007 10:11:29 GMTFri, 21 Sep 2007 10:11:29 GMT60中文q问题产生的由?/title><link>http://www.aygfsteel.com/keweibo/articles/146931.html</link><dc:creator>KE</dc:creator><author>KE</author><pubDate>Thu, 20 Sep 2007 13:46:00 GMT</pubDate><guid>http://www.aygfsteel.com/keweibo/articles/146931.html</guid><wfw:comment>http://www.aygfsteel.com/keweibo/comments/146931.html</wfw:comment><comments>http://www.aygfsteel.com/keweibo/articles/146931.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/keweibo/comments/commentRss/146931.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/keweibo/services/trackbacks/146931.html</trackback:ping><description><![CDATA[<p>中文q问题产生的由?/p> <p> 在计机中,只有二进制的数据Q不数据是在内存中Q还是在外部讑֤上?br /> 对于我们所看到的字W,也是以二q制数据的Ş式存在的。不同的字符对应?br /> 二进制数的规则,是字符的编码。字W编码的集合UCؓ字符集?/p> <p>常用的字W集<br /> 1 ASCII<br /> 2 ISO8859-1<br /> 3 GB2312和GBK</p> <p>  每个国家Q或者区域)都规定了计算Z息交换用的字W编码集Q这造成?br /> 交流上的困难。想象一下,你发送一中文邮件给一位远在西班牙的朋友,当邮?br /> 通过|络发送出ȝ时候,你所书写的中文字W会按照本地的字W集GBK转换成二q制<br /> ~码数据Q然后发送出厅R当你的朋友接收以邮Ӟ二进制数据)后,查看信gӞ?br /> 按照他所用的pȝ的字W集Q将二进制数据解码ؓ字符Q然而由于两U字W集之间~码<br /> 规则的不同,D转换出现q。这是因为,在不同的字符集之_同样的数字可能对<br /> 应了不同的符P也可能在另一U字W集中,该数字没也对应的W号?br />   决上q问题,l一全世界的字符~码Q由Unicode协会制定q发布了Unicode~码?br /> 4 Unicode<br /> 5 UTF-8</p> <p>对ؕ码生过E的分析</p> <p>  字符数据在各U不同的字符集之间{换时Q就有可能会出现q?br />   xml处理器在没有被预先通知的情况下会默认文档数据ؓUTF-8格式?br /> q样在你书写xml文档Ӟ存在了UTF-8字符集和本地字符q行转换的过E?br /> 当向xml文档中写入数据的时候,需要将本地字符集编码的数据转换为UTF-8<br /> Q而在输出字符数据的时候,则需要将UTF-8~码转换为本地字W集~码?br /> 从上q的q程来看Q写入和输出的过E是可逆的。理应不会出C文ؕ码问?br /> 然而,实际应用的情形,比上q的q程要复杂的多。在WEB应用中,通过都包?br /> 览器、WEB服务器、WEB应用E序和数据库{部分,每一部分的都有可能用不<br /> 同的字符集,从而导致数据在各种字符之间转换Ӟ出现了ؕ码问题?/p> <img src ="http://www.aygfsteel.com/keweibo/aggbug/146931.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/keweibo/" target="_blank">KE</a> 2007-09-20 21:46 <a href="http://www.aygfsteel.com/keweibo/articles/146931.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>几种误解Q以及ؕ码生的原因和解军_?/title><link>http://www.aygfsteel.com/keweibo/articles/144979.html</link><dc:creator>KE</dc:creator><author>KE</author><pubDate>Thu, 13 Sep 2007 14:34:00 GMT</pubDate><guid>http://www.aygfsteel.com/keweibo/articles/144979.html</guid><wfw:comment>http://www.aygfsteel.com/keweibo/comments/144979.html</wfw:comment><comments>http://www.aygfsteel.com/keweibo/articles/144979.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/keweibo/comments/commentRss/144979.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/keweibo/services/trackbacks/144979.html</trackback:ping><description><![CDATA[几种误解Q以及ؕ码生的原因和解军_? <h5>3.1 Ҏ产生的误?/h5> <table cellspacing="0" cellpadding="3" border="0"> <tbody> <tr> <td class="top_1"> </td> <td class="top_2" align="center"><strong>对编码的误解</strong></td> </tr> <tr> <td class="con_1" noWrap align="center">误解一</td> <td class="con_2">在将“字节?#8221;转化?#8220;UNICODE 字符?#8221;Ӟ比如在读取文本文件时Q或者通过|络传输文本ӞҎ?#8220;字节?#8221;单地作ؓ<strong>单字节字W串</strong>Q采用每“一个字?#8221;是“一个字W?#8221;的方法进行{化?br /> <br /> 而实际上Q在非英文的环境中,应该?#8220;字节?#8221;作ؓ ANSI 字符Ԍ采用适当的编码来得到 UNICODE 字符Ԍ有可?#8220;多个字节”才能得到“一个字W?#8221;?br /> <br /> 通常Q一直在英文环境下做开发的E序员们Q容易有q种误解?/td> </tr> <tr> <td class="bot_1" noWrap align="center">误解?/td> <td class="bot_2">?DOSQWindows 98 {非 UNICODE 环境下,字符串都是以 ANSI ~码的字节Ş式存在的。这U以字节形式存在的字W串Q必ȝ道是哪种~码才能被正地使用。这使我们Ş成了一个惯性思维Q?#8220;字符串的~码”?br /> <br /> ?UNICODE 被支持后QJava 中的 String 是以字符?#8220;序号”来存储的Q不是以“某种~码的字?#8221;来存储的Q因此已l不存在“字符串的~码”q个概念了。只有在“字符?#8221;?#8220;字节?#8221;转化Ӟ或者,一?#8220;字节?#8221;当成一?ANSI 字符串时Q才有编码的概念?br /> <br /> 不少的h都有q个误解?/td> </tr> </tbody> </table> <p>W一U误解,往往是导致ؕ码生的原因。第二种误解Q往往D本来ҎU正的ؕ码问题变得更复杂?/p> <p>在这里,我们可以看到Q其中所讲的“误解一”Q即采用?#8220;一个字?#8221;是“一个字W?#8221;的{化方法,实际上也q同于采用 iso-8859-1 q行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作Q得到原始的“字节?#8221;。然后再使用正确?ANSI ~码Q比?string = new String(bytes, "GB2312")Q来得到正确?#8220;UNICODE 字符?#8221;?/p> <h5><a id="instances" name="instances"></a>3.2 ?UNICODE E序在不同语a环境间移植时的ؕ?/h5> <p>?UNICODE E序中的字符Ԍ都是以某U?ANSI ~码形式存在的。如果程序运行时的语a环境与开发时的语a环境不同Q将会导?ANSI 字符串的昄p|?/p> <p>比如Q在日文环境下开发的?UNICODE 的日文程序界面,拿到中文环境下运行时Q界面上显CZؕ码。如果这个日文程序界面改为采?UNICODE 来记录字W串Q那么当在中文环境下q行Ӟ界面上将可以昄正常的日文?/p> <p>׃客观原因Q有时候我们必d中文操作pȝ下运行非 UNICODE 的日文YӞq时我们可以采用一些工P比如Q南极星QAppLocale {,暂时的模拟不同的语言环境?/p> <h5>3.3 |页提交字符?/h5> <p>当页面中的表单提交字W串Ӟ首先把字W串按照当前面的编码,转化成字节串。然后再每个字节{化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码ؓ GB2312 的页面,提交 "? q个字符串时Q提交给服务器的内容?"%D6%D0"?/p> <p>在服务器端,Web 服务器把收到?"%D6%D0" 转化?[0xD6, 0xD0] 两个字节Q然后再Ҏ GB2312 ~码规则得到 "? 字?/p> <p>?Tomcat 服务器中Qrequest.getParameter() 得到qӞ常常是因为前面提到的“误解一”造成的。默认情况下Q当提交 "%D6%D0" l?Tomcat 服务器时Qrequest.getParameter() 返?[0x00D6, 0x00D0] 两个 UNICODE 字符Q而不是返回一?"? 字符。因此,我们需要?bytes = string.getBytes("iso-8859-1") 得到原始的字节串Q再?string = new String(bytes, "GB2312") 重新得到正确的字W串 "??/p> <h5>3.4 从数据库d字符?/h5> <p>通过数据库客LQ比?ODBC ?JDBCQ从数据库服务器中读取字W串Ӟ客户端需要从服务器获知所使用?ANSI ~码。当数据库服务器发送字节流l客LӞ客户端负责将字节按照正的~码转化?UNICODE 字符丌Ӏ?/p> <p>如果从数据库d字符串时得到qQ而数据库中存攄数据又是正确的,那么往往q是因ؓ前面提到?#8220;误解一”造成的。解决的办法q是通过 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字节串Q再重新使用正确的编码{化成字符丌Ӏ?/p> <h5>3.5 电子邮g中的字符?/h5> <p>当一D?Text 或?HTML 通过电子邮g传送时Q发送的内容首先通过一U指定的<strong>字符~码</strong>转化?#8220;字节?#8221;Q然后再?#8220;字节?#8221;通过一U指定的<strong>传输~码</strong>QContent-Transfer-EncodingQ进行{化得到另一?#8220;字节?#8221;。比如,打开一电子邮件源代码Q可以看到类似的内容Q?/p> <table cellspacing="0" cellpadding="6" width="100%" bgcolor="#eeeeee" border="1"> <tbody> <tr> <td class="code">Content-Type: text/plain;<br />         <font color="#ff0000">charset="gb2312"</font><br /> <font color="#ff0000">Content-Transfer-Encoding: base64</font><br /> <br /> sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==</td> </tr> </tbody> </table> <p>最常用?Content-Transfer-Encoding ?Base64 ?Quoted-Printable 两种。在对二q制文g或者中文文本进行{化时QBase64 得到?#8220;字节?#8221;?Quoted-Printable 更短。在对英文文本进行{化时QQuoted-Printable 得到?#8220;字节?#8221;?Base64 更短?/p> <p>邮g的标题,用了一U更短的格式来标?#8220;字符~码”?#8220;传输~码”。比如,标题内容?"?Q则在邮件源代码中表CZؓQ?/p> <table cellspacing="0" cellpadding="6" width="100%" bgcolor="#eeeeee" border="1"> <tbody> <tr> <td class="code"><span id="wmqeeuq" class="rem">// 正确的标题格?/span><br /> Subject: <span style="background-color: #ffff00">=?</span>GB2312<span style="background-color: #ffff00">?B?</span>1tA=<span style="background-color: #ffff00">?=</span></td> </tr> </tbody> </table> <p>其中Q?/p> <ul> <li>W一?#8220;=?”?#8220;?”中间的部分指定了字符~码Q在q个例子中指定的?GB2312? <li>“?”?#8220;?”中间?#8220;B”代表 Base64。如果是“Q”则代?Quoted-Printable? <li>最?#8220;?”?#8220;?=”之间的部分,是l过 GB2312 转化成字节串Q再l过 Base64 转化后的标题内容?</li> </ul> <p>如果“传输~码”改ؓ Quoted-PrintableQ同P如果标题内容?"?Q?/p> <table cellspacing="0" cellpadding="6" width="100%" bgcolor="#eeeeee" border="1"> <tbody> <tr> <td class="code"><span id="wmqeeuq" class="rem">// 正确的标题格?/span><br /> Subject: <span style="background-color: #ffff00">=?</span>GB2312<span style="background-color: #ffff00">?Q?</span>=D6=D0<span style="background-color: #ffff00">?=</span></td> </tr> </tbody> </table> <p>如果阅读邮g时出Cؕ码,一般是因ؓ“字符~码”?#8220;传输~码”指定有误Q或者是没有指定。比如,有的发邮件组件在发送邮件时Q标?"?Q?/p> <table cellspacing="0" cellpadding="6" width="100%" bgcolor="#eeeeee" border="1"> <tbody> <tr> <td class="code"><span id="wmqeeuq" class="rem">// 错误的标题格?/span><br /> Subject: <span style="background-color: #ffff00">=?</span><font color="#ff0000">ISO-8859-1</font><span style="background-color: #ffff00">?Q?</span>=D6=D0<span style="background-color: #ffff00">?=</span></td> </tr> </tbody> </table> <p>q样的表C,实际上是明确指明了标题ؓ [0x00D6, 0x00D0]Q即 "?Q而不?"??/p> <h4><a id="correct" name="correct"></a>4. 几种错误理解的纠?/h4> <h5>误解Q?#8220;ISO-8859-1 是国际编码?”</h5> <p>非也。iso-8859-1 只是单字节字W集中最单的一U,也就?#8220;字节~号”?#8220;UNICODE 字符~号”一致的那种~码规则。当我们要把一?#8220;字节?#8221;转化?#8220;字符?#8221;Q而又不知道它是哪一U?ANSI ~码Ӟ先暂时地?#8220;每一个字?#8221;作ؓ“一个字W?#8221;q行转化Q不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节丌Ӏ?/p> <h5>误解Q?#8220;Java 中,怎样知道某个字符串的内码Q?#8221;</h5> <p>Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符Ԍ不是 ANSI 字符丌Ӏ我们只需要把字符串作?#8220;抽象的符L?#8221;来看待。因此不存在字符串的内码的问题?/p> <div id="wmqeeuq" class="invisible" id="reference">文章引用自:<a href="" target=" href_cetemp=" ?></a> </div> <img src ="http://www.aygfsteel.com/keweibo/aggbug/144979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/keweibo/" target="_blank">KE</a> 2007-09-13 22:34 <a href="http://www.aygfsteel.com/keweibo/articles/144979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符Q字节和~码http://www.aygfsteel.com/keweibo/articles/144978.htmlKEKEThu, 13 Sep 2007 14:25:00 GMThttp://www.aygfsteel.com/keweibo/articles/144978.htmlhttp://www.aygfsteel.com/keweibo/comments/144978.htmlhttp://www.aygfsteel.com/keweibo/articles/144978.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/144978.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/144978.html字符Q字节和~码

[原创文章Q{载请保留或注明出处:http://www.regexlab.com/zh/encoding.htm]

U别Q中U?/p>

摘要Q本文介l了字符与编码的发展q程Q相x늚正确理解。D例说明了一些实际应用中Q编码的实现Ҏ。然后,本文讲述了通常对字W与~码的几U误解,׃q些误解而导致ؕ码生的原因Q以及消除ؕ码的办法。本文的内容늛?#8220;中文问题”Q?#8220;q问题”?/p>

掌握~码问题的关键是正确地理解相x念,~码所涉及的技术其实是很简单的。因此,阅读本文旉要慢d惻I多思考?/p>

引言

“字符与编?#8221;是一个被l常讨论的话题。即使这P时常出现的ؕ码仍然困扰着大家。虽然我们有很多的办法可以用来消除ؕ码,但我们ƈ不一定理解这些办法的内在原理。而有的ؕ码生的原因Q实际上׃底层代码本n有问题所D的。因此,不仅是初学者会对字W编码感到模p,有的底层开发h员同样对字符~码~Z准确的理解?/p>

回页?/a>

1. ~码问题的由来,相关概念的理?/h4>

1.1 字符与编码的发展

从计机对多国语a的支持角度看Q大致可以分Z个阶D:

  pȝ内码 说明
阶段一 ASCII 计算机刚开始只支持pQ其它语a不能够在计算Z存储和显C?/td> 英文 DOS
阶段?/td> ANSI~码
Q本地化Q?/td>
Z计算机支持更多语aQ通常使用 0x80~0xFF 范围?2 个字节来表示 1 个字W。比如:汉字 '? 在中文操作系l中Q?[0xD6,0xD0] q两个字节存储?br />
不同的国家和地区制定了不同的标准Q由此生了 GB2312, BIG5, JIS {各自的~码标准。这些?2 个字节来代表一个字W的各种汉字延׾~码方式Q称?strong> ANSI ~码。在体中文系l下QANSI ~码代表 GB2312 ~码Q在日文操作pȝ下,ANSI ~码代表 JIS ~码?br />
不同 ANSI ~码之间互不兼容Q当信息在国际间交流Ӟ无法属于两U语a的文字,存储在同一D?strong> ANSI ~码的文本中?/td>
中文 DOSQ中?Windows 95/98Q日?Windows 95/98
阶段?/td> UNICODE
Q国际化Q?/td>
Z使国际间信息交流更加方便Q国际组l制定了 UNICODE 字符?/strong>Qؓ各种语言中的每一个字W设定了l一q且唯一的数字编P以满语言、跨q_q行文本转换、处理的要求?/td> Windows NT/2000/XPQLinuxQJava

字符串在内存中的存放ҎQ?/p>

?ASCII 阶段Q?strong>单字节字W串使用一个字节存放一个字W(SBCSQ。比如,"Bob123" 在内存中为:

42 6F 62 31 32 33 00
B o b 1 2 3 \0

在?ANSI ~码支持多种语言阶段Q每个字W用一个字节或多个字节来表C(MBCSQ,因此Q这U方式存攄字符也被UC多字节字W?/strong>。比如,"中文123" 在中?Windows 95 内存中ؓ7个字节,每个汉字?个字节,每个英文和数字字W占1个字节:

D6 D0 CE C4 31 32 33 00
?/td> ?/td> 1 2 3 \0

?UNICODE 被采用之后,计算机存攑֭W串Ӟ改ؓ存放每个字符?UNICODE 字符集中的序受目前计机一般?2 个字节(16 位)来存放一个序PDBCSQ,因此Q这U方式存攄字符也被UC宽字节字W?/strong>。比如,字符?"中文123" ?Windows 2000 下,内存中实际存攄?5 个序P

2D 4E 87 65 31 00 32 00 33 00 00 00      ← ?x86 CPU 中,低字节在?/font>
?/td> ?/td> 1 2 3 \0  

一共占 10 个字节?/p>

回页?/a>

1.2 字符Q字节,字符?/h5>

理解~码的关键,是要把字W的概念和字节的概念理解准确。这两个概念ҎhQ我们在此做一下区分:

  概念描述 举例
字符 Z使用的记P抽象意义上的一个符受?/td> '1', '?, 'a', '$', 'K?, ……
字节 计算Z存储数据的单元,一?位的二进制数Q是一个很具体的存储空间?/td> 0x01, 0x45, 0xFA, ……
ANSI
字符?/td>
在内存中Q如?#8220;字符”是以 ANSI ~码形式存在的,一个字W可能用一个字节或多个字节来表C,那么我们U这U字W串?ANSI 字符?/strong>或?strong>多字节字W串?/td> "中文123"
Q占7字节Q?/span>
UNICODE
字符?/td>
在内存中Q如?#8220;字符”是以?UNICODE 中的序号存在的,那么我们U这U字W串?UNICODE 字符?/strong>或?strong>宽字节字W串?/td> L"中文123"
Q占10字节Q?/span>

׃不同 ANSI ~码所规定的标准是不相同的Q因此,对于一个给定的多字节字W串Q我们必ȝ道它采用的是哪一U编码规则,才能够知道它包含了哪?#8220;字符”。而对?UNICODE 字符?/strong>来说Q不在什么环境下Q它所代表?#8220;字符”内容L不变的?/p>

回页?/a>

1.3 字符集与~码

各个国家和地区所制定的不?ANSI ~码标准中,都只规定了各自语a所需?#8220;字符”。比如:汉字标准QGB2312Q中没有规定韩国语字W怎样存储。这?ANSI ~码标准所规定的内容包含两层含义:

  1. 使用哪些字符。也是说哪些汉字,字母和符号会被收入标准中。所包含“字符”的集合就叫做“字符?/strong>”?
  2. 规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储Q这个规定就叫做“~码”?

各个国家和地区在制定~码标准的时候,“字符的集?#8221;?#8220;~码”一般都是同时制定的。因此,q_我们所说的“字符?#8221;Q比如:GB2312, GBK, JIS {,除了?#8220;字符的集?#8221;q层含义外,同时也包含了“~码”的含义?/p>

UNICODE 字符?/strong>”包含了各U语a中用到的所?#8220;字符”。用来给 UNICODE 字符集编码的标准有很多种Q比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig {?/p>

回页?/a>

1.4 常用的编码简?/h5>

单介l一下常用的~码规则Qؓ后边的章节做一个准备。在q里Q我们根据编码规则的特点Q把所有的~码分成三类Q?/p>
分类 ~码标准 说明
单字节字W编?/td> ISO-8859-1 最单的~码规则Q每一个字节直接作Z?UNICODE 字符。比如,[0xD6, 0xD0] q两个字节,通过 iso-8859-1 转化为字W串Ӟ直接得?[0x00D6, 0x00D0] 两个 UNICODE 字符Q即 "ÖÐ"?br />
反之Q将 UNICODE 字符串通过 iso-8859-1 转化为字节串Ӟ只能正常转化 0~255 范围的字W?/td>
ANSI ~码 GB2312,
BIG5,
Shift_JIS,
ISO-8859-2 ……
?UNICODE 字符串通过 ANSI ~码转化?#8220;字节?#8221;ӞҎ各自~码的规定,一?UNICODE 字符可能转化成一个字节或多个字节?br />
反之Q将字节串{化成字符串时Q也可能多个字节转化成一个字W。比如,[0xD6, 0xD0] q两个字节,通过 GB2312 转化为字W串Ӟ得?[0x4E2D] 一个字W,?'? 字?br />
“ANSI ~码”的特点:
1. q些“ANSI ~码标准”都只能处理各自语a范围之内?UNICODE 字符?br /> 2. “UNICODE 字符”?#8220;转换出来的字?#8221;之间的关pLZؓ规定的?/td>
UNICODE ~码 UTF-8,
UTF-16, UnicodeBig ……
?#8220;ANSI ~码”cM的,把字W串通过 UNICODE ~码转化?#8220;字节?#8221;Ӟ一?UNICODE 字符可能转化成一个字节或多个字节?br />
?#8220;ANSI ~码”不同的是Q?br /> 1. q些“UNICODE ~码”能够处理所有的 UNICODE 字符?br /> 2. “UNICODE 字符”?#8220;转换出来的字?#8221;之间是可以通过计算得到的?/td>

我们实际上没有必要去q每一U编码具体把某一个字W编码成了哪几个字节Q我们只需要知?#8220;~码”的概念就是把“字符”转化?#8220;字节”可以了。对?#8220;UNICODE ~码”Q由于它们是可以通过计算得到的,因此Q在Ҏ的场合,我们可以M解某一U?#8220;UNICODE ~码”是怎样的规则?/p>

回页?/a>

2. 字符与编码在E序中的实现

2.1 E序中的字符与字?/h5>

?C++ ?Java 中,用来代表“字符”?#8220;字节”的数据类型,以及q行~码的方法:

cd或操?/strong> C++ Java
字符 wchar_t char
字节 char byte
ANSI 字符?/td> char[] byte[]
UNICODE 字符?/td> wchar_t[] String
字节?#8594;字符?/td> mbstowcs(), MultiByteToWideChar() string = new String(bytes, "encoding")
字符?#8594;字节?/td> wcstombs(), WideCharToMultiByte() bytes = string.getBytes("encoding")

以上需要注意几点:

  1. Java 中的 char 代表一?#8220;UNICODE 字符Q宽字节字符Q?#8221;Q?C++ 中的 char 代表一个字节?
  2. MultiByteToWideChar() ?WideCharToMultiByte() ?Windows API 函数?

回页?/a>

2.2 C++ 中相兛_现方?/h5>

声明一D字W串帔RQ?/p>
// ANSI 字符Ԍ内容长度 7 字节
char
     sz[20] = "中文123";

// UNICODE 字符Ԍ内容长度 5 ?wchar_tQ?0 字节Q?/span>
wchar_t wsz[20] = L"\x4E2D\x6587\x0031\x0032\x0033";

UNICODE 字符串的 I/O 操作Q字W与字节的{换操作:

// q行时设定当?ANSI ~码QVC 格式
setlocale(LC_ALL, ".936");

// GCC 中格?/span>
setlocale(LC_ALL, "zh_CN.GBK");

// Visual C++ 中用小?%sQ按?setlocale 指定~码输出到文?br /> // GCC 中用大?%S
fwprintf(fp, L"%s\n", wsz);

// ?UNICODE 字符串按?setlocale 指定的编码{换成字节
wcstombs(sz, wsz, 20);
// 把字节串按照 setlocale 指定的编码{换成 UNICODE 字符?br />
mbstowcs(wsz, sz, 20);

?Visual C++ 中,UNICODE 字符串常量有更简单的表示Ҏ。如果源E序的编码与当前默认 ANSI ~码不符Q则需要?#pragma setlocaleQ告诉编译器源程序用的~码Q?/p>
// 如果源程序的~码与当前默?ANSI ~码不一_
// 则需要此行,~译时用来指明当前源E序使用的编?/span>
#pragma setlocale
(".936")

// UNICODE 字符串常量,内容长度 10 字节
wchar_t wsz[20] = L"中文123";

以上需要注?#pragma setlocale ?setlocale(LC_ALL, "") 的作用是不同的,#pragma setlocale 在编译时起作用,setlocale() 在运行时起作用?/p>

回页?/a>

2.3 Java 中相兛_现方?/h5>

字符串类 String 中的内容?UNICODE 字符Ԍ

// Java 代码Q直接写中文
String
string = "中文123";

// 得到长度?5Q因为是 5 个字W?/span>
System.out.println(string.length());

字符?I/O 操作Q字W与字节转换操作。在 Java ?java.io.* 中,?#8220;Stream”l尾的类一般是用来操作“字节?#8221;的类Q以“Reader”Q?#8220;Writer”l尾的类一般是用来操作“字符?#8221;的类?/p>
// 字符串与字节串间怺转化

// 按照 GB2312 得到字节Q得到多字节字符Ԍ

byte
[] bytes = string.getBytes("GB2312");

// 从字节按?GB2312 得到 UNICODE 字符?/span>
string = new String(bytes, "GB2312");

// 要将 String 按照某种~码写入文本文gQ有两种ҎQ?br />
// W一U办法:?Stream cd入已l按照指定编码{化好的字节串

OutputStream os = new FileOutputStream("1.txt");
os.write(bytes);
os.close();

// W二U办法:构造指定编码的 Writer 来写入字W串
Writer ow = new OutputStreamWriter(new FileOutputStream("2.txt"), "GB2312");
ow.write(string);
ow.close();

/* 最后得到的 1.txt ?2.txt 都是 7 个字?*/

如果 java 的源E序~码与当前默?ANSI ~码不符Q则在编译的时候,需要指明一下源E序的编码。比如:

E:\>javac -encoding BIG5 Hello.java

以上需要注意区分源E序的编码与 I/O 操作的编码,前者是在编译时起作用,后者是在运行时起作用?/p>

回页?/a>

3. 几种误解Q以及ؕ码生的原因和解军_?/h4>

3.1 Ҏ产生的误?/h5>
  对编码的误解
误解一 在将“字节?#8221;转化?#8220;UNICODE 字符?#8221;Ӟ比如在读取文本文件时Q或者通过|络传输文本ӞҎ?#8220;字节?#8221;单地作ؓ单字节字W串Q采用每“一个字?#8221;是“一个字W?#8221;的方法进行{化?br />
而实际上Q在非英文的环境中,应该?#8220;字节?#8221;作ؓ ANSI 字符Ԍ采用适当的编码来得到 UNICODE 字符Ԍ有可?#8220;多个字节”才能得到“一个字W?#8221;?br />
通常Q一直在英文环境下做开发的E序员们Q容易有q种误解?/td>
误解?/td> ?DOSQWindows 98 {非 UNICODE 环境下,字符串都是以 ANSI ~码的字节Ş式存在的。这U以字节形式存在的字W串Q必ȝ道是哪种~码才能被正地使用。这使我们Ş成了一个惯性思维Q?#8220;字符串的~码”?br />
?UNICODE 被支持后QJava 中的 String 是以字符?#8220;序号”来存储的Q不是以“某种~码的字?#8221;来存储的Q因此已l不存在“字符串的~码”q个概念了。只有在“字符?#8221;?#8220;字节?#8221;转化Ӟ或者,一?#8220;字节?#8221;当成一?ANSI 字符串时Q才有编码的概念?br />
不少的h都有q个误解?/td>

W一U误解,往往是导致ؕ码生的原因。第二种误解Q往往D本来ҎU正的ؕ码问题变得更复杂?/p>

在这里,我们可以看到Q其中所讲的“误解一”Q即采用?#8220;一个字?#8221;是“一个字W?#8221;的{化方法,实际上也q同于采用 iso-8859-1 q行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作Q得到原始的“字节?#8221;。然后再使用正确?ANSI ~码Q比?string = new String(bytes, "GB2312")Q来得到正确?#8220;UNICODE 字符?#8221;?/p>

回页?/a>

3.2 ?UNICODE E序在不同语a环境间移植时的ؕ?/h5>

?UNICODE E序中的字符Ԍ都是以某U?ANSI ~码形式存在的。如果程序运行时的语a环境与开发时的语a环境不同Q将会导?ANSI 字符串的昄p|?/p>

比如Q在日文环境下开发的?UNICODE 的日文程序界面,拿到中文环境下运行时Q界面上显CZؕ码。如果这个日文程序界面改为采?UNICODE 来记录字W串Q那么当在中文环境下q行Ӟ界面上将可以昄正常的日文?/p>

׃客观原因Q有时候我们必d中文操作pȝ下运行非 UNICODE 的日文YӞq时我们可以采用一些工P比如Q南极星QAppLocale {,暂时的模拟不同的语言环境?/p>

回页?/a>

3.3 |页提交字符?/h5>

当页面中的表单提交字W串Ӟ首先把字W串按照当前面的编码,转化成字节串。然后再每个字节{化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码ؓ GB2312 的页面,提交 "? q个字符串时Q提交给服务器的内容?"%D6%D0"?/p>

在服务器端,Web 服务器把收到?"%D6%D0" 转化?[0xD6, 0xD0] 两个字节Q然后再Ҏ GB2312 ~码规则得到 "? 字?/p>

?Tomcat 服务器中Qrequest.getParameter() 得到qӞ常常是因为前面提到的“误解一”造成的。默认情况下Q当提交 "%D6%D0" l?Tomcat 服务器时Qrequest.getParameter() 返?[0x00D6, 0x00D0] 两个 UNICODE 字符Q而不是返回一?"? 字符。因此,我们需要?bytes = string.getBytes("iso-8859-1") 得到原始的字节串Q再?string = new String(bytes, "GB2312") 重新得到正确的字W串 "??/p>

回页?/a>

3.4 从数据库d字符?/h5>

通过数据库客LQ比?ODBC ?JDBCQ从数据库服务器中读取字W串Ӟ客户端需要从服务器获知所使用?ANSI ~码。当数据库服务器发送字节流l客LӞ客户端负责将字节按照正的~码转化?UNICODE 字符丌Ӏ?/p>

如果从数据库d字符串时得到qQ而数据库中存攄数据又是正确的,那么往往q是因ؓ前面提到?#8220;误解一”造成的。解决的办法q是通过 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字节串Q再重新使用正确的编码{化成字符丌Ӏ?/p>

回页?/a>

3.5 电子邮g中的字符?/h5>

当一D?Text 或?HTML 通过电子邮g传送时Q发送的内容首先通过一U指定的字符~码转化?#8220;字节?#8221;Q然后再?#8220;字节?#8221;通过一U指定的传输~码QContent-Transfer-EncodingQ进行{化得到另一?#8220;字节?#8221;。比如,打开一电子邮件源代码Q可以看到类似的内容Q?/p>
Content-Type: text/plain;
        charset="gb2312"
Content-Transfer-Encoding: base64

sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==

最常用?Content-Transfer-Encoding ?Base64 ?Quoted-Printable 两种。在对二q制文g或者中文文本进行{化时QBase64 得到?#8220;字节?#8221;?Quoted-Printable 更短。在对英文文本进行{化时QQuoted-Printable 得到?#8220;字节?#8221;?Base64 更短?/p>

邮g的标题,用了一U更短的格式来标?#8220;字符~码”?#8220;传输~码”。比如,标题内容?"?Q则在邮件源代码中表CZؓQ?/p>
// 正确的标题格?/span>
Subject: =?GB2312?B?1tA=?=

其中Q?/p>

  • W一?#8220;=?”?#8220;?”中间的部分指定了字符~码Q在q个例子中指定的?GB2312?
  • “?”?#8220;?”中间?#8220;B”代表 Base64。如果是“Q”则代?Quoted-Printable?
  • 最?#8220;?”?#8220;?=”之间的部分,是l过 GB2312 转化成字节串Q再l过 Base64 转化后的标题内容?

如果“传输~码”改ؓ Quoted-PrintableQ同P如果标题内容?"?Q?/p>
// 正确的标题格?/span>
Subject: =?GB2312?Q?=D6=D0?=

如果阅读邮g时出Cؕ码,一般是因ؓ“字符~码”?#8220;传输~码”指定有误Q或者是没有指定。比如,有的发邮件组件在发送邮件时Q标?"?Q?/p>
// 错误的标题格?/span>
Subject: =?ISO-8859-1?Q?=D6=D0?=

q样的表C,实际上是明确指明了标题ؓ [0x00D6, 0x00D0]Q即 "ÖÐ"Q而不?"??/p>

回页?/a>

4. 几种错误理解的纠?/h4>

误解Q?#8220;ISO-8859-1 是国际编码?”

非也。iso-8859-1 只是单字节字W集中最单的一U,也就?#8220;字节~号”?#8220;UNICODE 字符~号”一致的那种~码规则。当我们要把一?#8220;字节?#8221;转化?#8220;字符?#8221;Q而又不知道它是哪一U?ANSI ~码Ӟ先暂时地?#8220;每一个字?#8221;作ؓ“一个字W?#8221;q行转化Q不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节丌Ӏ?/p>

误解Q?#8220;Java 中,怎样知道某个字符串的内码Q?#8221;

Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符Ԍ不是 ANSI 字符丌Ӏ我们只需要把字符串作?#8220;抽象的符L?#8221;来看待。因此不存在字符串的内码的问题?/p>

KE 2007-09-13 22:25 发表评论
]]>Tomcat中文q问题原因和解x?http://www.aygfsteel.com/keweibo/articles/144872.htmlKEKEThu, 13 Sep 2007 07:26:00 GMThttp://www.aygfsteel.com/keweibo/articles/144872.htmlhttp://www.aygfsteel.com/keweibo/comments/144872.htmlhttp://www.aygfsteel.com/keweibo/articles/144872.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/144872.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/144872.htmlTomcat中文q问题原因和解x?/a> 自从接触Java和JSP以来Q就不断与Java的中文ؕ码问题打交道Q现在终于得Cd的解冻I现将我们的解军_得与大家׃n?

  一、Java中文问题的由?/p>

  Java的内核和class文g是基于unicode的,qJavaE序h良好的跨q_性,但也带来了一些中文ؕ码问题的ȝ。原因主要有两方面,Java和JSP文g本n~译时生的q问题和JavaE序于其他媒介交互生的q问题?/p>

  首先JavaQ包括JSPQ源文g中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP~译成class文gq程中,使用的编码方式与源文件的~码不一_׃出现q。基于这Uؕ码,在Java文g中尽量不要写中文Q注释部分不参与~译Q写中文没关p)Q如果必d的话Q尽量手动带参数Qecoding GBK或-ecoding gb2312~译Q对于JSPQ在文g头加?lt;%@ page contentType="text/html;charset=GBK"%>?lt;%@ page contentType="text/html;charset=gb2312"%>基本上就能解册cMؕ码问题?/p>

  本文要重点讨论的是第二类qQ即JavaE序与其他存储媒介交互时产生的ؕ码。很多存储媒介,如数据库Q文Ӟ等的存储方式都是基于字节流的,JavaE序与这些媒介交互时׃发生字符(char)与字?byte)之间的{换,例如从页面提交表单中提交的数据在JavaE序里显CZؕ码等情况?/p>

  如果在以上{换过E中使用的编码方式与字节原有的编码不一_很可能就会出Cؕ码?/p>

  二、解x?/p>

  对于行的Tomcat来说Q有以下两种解决ҎQ?/p>

  1) 更改 D:\Tomcat\conf\server.xmlQ指定浏览器的编码格式ؓ“体中?#8221;Q?/p>

  Ҏ是找?server.xml 中的

    <Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
    enableLookups="false" redirectPort="8443" acceptCount="100"
    connectionTimeout="20000" disableUploadTimeout="true" URIEncoding='GBK' />

  标记Q粗体字是我d的?/p>

  可以q样验证你的更改是否成功Q在更改前,在你出现q的页面的IE览器,点击菜单“查看|编?#8221;Q会发现“西欧(ISO)”处于选中状态。而更改后Q点击菜?#8220;查看|编?#8221;Q会发现“体中?GB2312)”处于选中状态?/p>

  b)更该 Java E序Q我的程序是q样的:

public class ThreeParams extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
      response.setContentType("text/html; charset=GBK");
      ...
  } 
}

  _体字是必需要有的,它的作用是让览器把Unicode字符转换为GBK字符。这样页面的内容和浏览器的显C模式都设成了GBKQ就不会q了?br />
本文来自http://www.aygfsteel.com/kemi/archive/2007/07/10/129220.html



KE 2007-09-13 15:26 发表评论
]]>
~码基本知识http://www.aygfsteel.com/keweibo/articles/144868.htmlKEKEThu, 13 Sep 2007 07:12:00 GMThttp://www.aygfsteel.com/keweibo/articles/144868.htmlhttp://www.aygfsteel.com/keweibo/comments/144868.htmlhttp://www.aygfsteel.com/keweibo/articles/144868.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/144868.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/144868.html

最早的~码是iso8859-1Q和ascii~码怼。但Z方便表示各种各样的语aQ逐渐出现了很?nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="color: #6600ff; border-bottom: #6600ff 1px dotted; background-color: transparent; text-decoration: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">标准~码Q重要的有如下几?

1. iso8859-1

属于单字节编码,最多能表示的字W范围是0-255Q应用于英文pd。比如,字母a的编码ؓ0x61=97?/p>

很明显,iso8859-1~码表示的字W范围很H,无法表示中文字符。但是,׃是单字节~码Q和计算机最基础的表C单位一_所以很多时候,仍旧使用iso8859-1~码来表C。而且在很多协议上Q默认用该~码。比如,虽然"中文"两个字不存在iso8859-1~码Q以gb2312~码ZQ应该是"d6d0 cec4"两个字符Q用iso8859-1~码的时候则它拆开?个字节来表示Q?d6 d0 ce c4"Q事实上Q在q行存储的时候,也是以字节ؓ单位处理的)。而如果是UTF~码Q则?个字?e4 b8 ad e6 96 87"。很明显Q这U表C?nobr oncontextmenu="return false;" onmousemove="kwM(3);" id="key3" onmouseover="kwE(event,3, this);" style="color: #6600ff; border-bottom: #6600ff 1px dotted; background-color: transparent; text-decoration: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">Ҏq需要以另一U编码ؓ基础?/p>

2. GB2312/GBK

q就是汉子的国标码,专门用来表示汉字Q是双字节编码,而英文字母和iso8859-1一_兼容iso8859-1~码Q。其中gbk~码能够用来同时表示J体字和体字Q而gb2312只能表示体字Qgbk是兼容gb2312~码的?/p>

3. unicode

q是最l一的编码,可以用来表示所有语a的字W,而且是定长双字节Q也有四字节的)~码Q包括英文字母在内。所以可以说它是不兼容iso8859-1~码的,也不兼容M~码。不q,相对于iso8859-1~码来说Quniocode~码只是在前面增加了一?字节Q比如字母a?00 61"?/p>

需要说明的是,定长~码便于计算机处理(注意GB2312/GBK不是定长~码Q,而unicode又可以用来表C所有字W,所以在很多软g内部是用unicode~码来处理的Q比?nobr oncontextmenu="return false;" onmousemove="kwM(4);" id="key4" onmouseover="kwE(event,4, this);" style="color: #6600ff; border-bottom: #6600ff 1px dotted; background-color: transparent; text-decoration: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">java?/p>

4. UTF

考虑到unicode~码不兼容iso8859-1~码Q而且Ҏ占用更多的空_因ؓ对于英文字母Qunicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而生了utf~码Qutf~码兼容iso8859-1~码Q同时也可以用来表示所有语a的字W,不过Qutf~码是不定长~码Q每一个字W的长度?-6个字节不{。另外,utf~码自带?/nobr>的校验功能。一般来Ԍ英文字母都是用一个字节表C,而汉字用三个字节?/p>

注意Q虽然说utf是ؓ了用更的I间而用的Q但那只是相对于unicode~码来说Q如果已l知道是汉字Q则使用GB2312/GBK无疑是最节省的。不q另一斚wQ值得说明的是Q虽然utf~码Ҏ字?个字节,但即使对于汉字网,utf~码也会比unicode~码节省Q因为网中包含了很多的英文字符?br />
本文来自http://digest.softhouse.com.cn/digest/show/28639.html



KE 2007-09-13 15:12 发表评论
]]>
常用字符集编码的概要Ҏ(二)http://www.aygfsteel.com/keweibo/articles/144859.htmlKEKEThu, 13 Sep 2007 07:01:00 GMThttp://www.aygfsteel.com/keweibo/articles/144859.htmlhttp://www.aygfsteel.com/keweibo/comments/144859.htmlhttp://www.aygfsteel.com/keweibo/articles/144859.html#Feedback0http://www.aygfsteel.com/keweibo/comments/commentRss/144859.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/144859.htmlBIG5

Big5是双字节~码Q高字节~码范围?x81-0xFEQ低字节~码范围?x40-0x7E?xA1-0xFE。和GBK相比Q少了低字节?x80-0xA0的组合?x8140-0xA0FE是保留区域,用于用户造字区?/p>

Big5收录的汉字只包括J体汉字Q不包括体汉字,一些生ȝ汉字也没有收录。GBK收录的日文假名字W、俄文字WBig5也没有收录。因为Big5当中收录的字W有限,因此有很多在Big5基础上扩展的~码Q如倚天中文pȝ。Windowspȝ上用的代码CP950也可以理解ؓ是对Big5的扩展,在Big5的基上增加了7个汉字和一些符受Big5~码对应的字W集是GBK字符集的子集Q也是说Big5收录的字W是GBK收录字符的一部分Q但相同字符的编码不同?/p>

因ؓBig5也占用了ASCII的编码空_低字节所使用?x40-0x7EQ,所以Big5~码在一些环境下存在和GBK~码相同的问题,即低字节范围?x40-0x7E的字W有可能会被误处理,其是低字节?x5CQ?/"Q和0x7CQ?|"Q的字符。可以参?strong>GBK一节相应说明?/p>

管有些区别Q大多数情况下可以把CP950当作Big5的别名?/p>

ISO-8859-1

ISO-8859-1~码是单字节~码Q向下兼容ASCIIQ其~码范围?x00-0xFFQ?x00-0x7F之间完全和ASCII一_0x80-0x9F之间是控制字W,0xA0-0xFF之间是文字符受?/p>

ISO-8859-1收录的字W除ASCII收录的字W外Q还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字W号。欧元符号出现的比较晚,没有被收录在ISO-8859-1当中?/p>

因ؓISO-8859-1~码范围使用了单字节内的所有空_在支持ISO-8859-1的系l中传输和存储其他Q何编码的字节都不会被抛弃。换a之,把其他Q何编码的字节当作ISO-8859-1~码看待都没有问题。这是个很重要的Ҏ,MySQL数据库默认编码是Latin1是利用了这个特性。ASCII~码是一?位的容器QISO-8859-1~码是一?位的容器?/p>

Latin1是ISO-8859-1的别名,有些环境下写作Latin-1?/p>

UCS-2和UTF-16

Unicodel织?a >ISOl织都试囑֮义一个超大字W集Q目的是要涵盖所有语a使用的字W以及其他学U用的一些特D符Pq个字符集就是通用字符集(UCSQUniversal Character SetQ。这两个l织l过协调Q虽然在各自发展Q但定义的字W位|是完全一致的。ISO相应的标准是ISO 10646。Unicode和ISO 10646都在不断的发展过E中Q所以会有不同的版本h标明不同的发展阶D,每个Unicode版本号都能找到相对应的ISO 10646版本受?/p>

ISO 10646标准定义了一?1位的字符集。前两个字节的位|(0x0000-0xFFFDQ被UCؓ基本多语a面(Basic Multilingual Plane, BMPQ?Q超Z个字节的范围UC辅助语言面。BMP基本包括了所有语a中绝大多数字W,所以只要支持BMP可以支持绝大多数场合下的应用。Unicode 3.0对应的字W集在BMP范围内?/p>

UCS字符集ؓ每个字符分配了一个位|,通常?#8220;U”再加上某个字W在UCS中位|的16q制C个字W的UCS表示Q例?#8220;U+0041”表示字符“A”。UCS字符U+0000到U+00FF与ISO-8859-1完全一致?/p>

UCS-2、UTF-16是UCS字符集(或者说是Unicode字符集)实际应用中的具体~码方式。UCS-2是两个字节的{宽~码Q因为只是用了两个字节的编码空_所以只能对BMP中的字符做编码。UTF-16是变长编码,用两个字节对BMP内的字符~码Q用4个字节对出BMP范围的辅助^面内的字W作~码?/p>

UCS-2不同于GBK和Big5Q它是真正的{宽~码Q每个字W都使用两个字节Q这个特性在字符串截断和字符数计时非常方便?/span>

UTF-16是UCS-2的超集,UTF-16~码的两字节~码方式完全和UCS-2相同Q也是说在BMP的框架内UCS-2完全{同与UTF-16。实际情况当中常常把UCS-16当作UCS-2的别名?/p>

UCS-2和UTF-16在存储和传输时会使用两种不同的字节序Q分别是big endian和little endianQ大֒尾Q。例?#8220;?#8221;QU+554AQ用big endian表示是0x554AQ用little endian表示是0x4A55。UCS-2和UTF-16默认的字节序是big endian方式。在传输q程中ؓ了说明字节序需要在字节前加上BOMQByte order MarkQ,0xFEFF表示是big endianQ?xFFFE表示是little endian。UCS-2BE、UCS-2LE是实际应用中使用的编码名Uͼ对应着big endian和little endianQUTF-16BE、UTF-16LE也是如此。因为默认是BE字节序,所以可以把UCS-2当做是UCS-2BE的别名?/span>

在UCS~码中有一个叫?#8220;ZERO WIDTH NO-BREAK SPACE”的字W,它的~码是U+FEFFQ是个没有实际意义的字符。UCS规范我们在传输字节流前,先传输字W?#8220;ZERO WIDTH NO-BREAK SPACE”Q如果传输的ZERO WIDTH NO-BREAK SPACE?xFEFFp明是big endianQ反之就是little endian?/span>

UCS-2和UTF-16也可以理解ؓ和ASCII以及ISO-8859-1兼容Q在ASCII~码或者ISO-8859-1~码的每个字节前加上0x00Q就得到相应字符的UCS-2~码?/span>

UCS-2和UTF-16中会使用0x00作ؓ某个字符~码的一部分Q某些系l会?x00当作字符串结束的标志Q在处理UCS-2或UTF-16~码时会出现问题?/span>

UTF-8

UTF-8是UCS字符集的另一U编码方式,UTF-16的每个单元是两个字节Q?6位)Q而UTF-8的每个单元是一个字节(8位)。UTF-16中用一个或两个双字节表CZ个字W,UTF-8中用一个或几个单字节表CZ个字W?/p>

可以认ؓUTF-8~码是根据一定规律从UCS-2转换得到的,从UCS-2到UTF-8之间有以下{换关p:

UCS-2 UTF-8
U+0000 - U+007F 0xxxxxxx
U+0080 - U+07FF 110xxxxx 10xxxxxx
U+0800 - U+FFFF 1110xxxx 10xxxxxx 10xxxxxx

例如“?#8221;字的UCS-2~码?x554AQ对应的二进制是0101 0101 0100 1010Q{成UTF-8~码之后的二q制?110 0101 10 010101 10 001010Q对应的十六q制?xE5958A?/p>

UCS-4也是一UUCS字符集的~码方式Q是使用4个字节的{宽~码Q可以用UCS-4来表CBMP之外的辅助面字符。UCS-2中每两个字节前再加上0x0000得CBMP字符的UCS-4~码。从UCS-4到UTF-8也存在{换关p,Ҏq种转换关系QUTF-8最多可以用六个字节来~码UCS-4?/p>

ҎUTF-8的生成规律和UCS字符集的Ҏ,可以看到UTF-8h的特性:

  1. UTF-8完全和ASCII兼容Q也是说ASCII对应的字W在UTF-8中和ASCII~码完全一致。范围在0x00-0x7F之内的字W一定是ASCII字符Q不可能是其他字W的一部分。GBK和Big5都存在的~陷在UTF-8中是不存在的?
  2. 大于U+007F的UCS字符Q在UTF-8~码中至是两个字节?
  3. UTF-8中的每个字符~码的首字节d0x00-0xFD之间Q不考虑UCS-4支持的情况,首字节在0x00-0xEF之间Q。根据首字节可以判断之后连l几个字节?
  4. 非首字节的其他字节都?x80-0xBF之间Q?xFE?xFF在UTF-8中没有被用到?
  5. GBK~码中的汉字字符都在UCS-2中的范围都在U+0800 - U+FFFF之间Q所以每个GBK~码中的汉字字符的UTF-8~码都是3个字节。但GBK中包含的其他字符的UTF-8~码׃一定是3个字节了Q如GBK中的俄文字符?

在UTF-8的编码的传输q程中即使丢掉一个字节,Ҏ~码规律也很Ҏ定位丢掉的位|,不会影响到其他字W。在其他双字节编码中Q一旦损׃个字节,׃影响到此字节之后的所有字W。从q点可以看出UTF-8~码非常适合作ؓ传输~码?



KE 2007-09-13 15:01 发表评论
]]>常用字符集编码的概要Ҏ(一Q?/title><link>http://www.aygfsteel.com/keweibo/articles/144857.html</link><dc:creator>KE</dc:creator><author>KE</author><pubDate>Thu, 13 Sep 2007 07:00:00 GMT</pubDate><guid>http://www.aygfsteel.com/keweibo/articles/144857.html</guid><wfw:comment>http://www.aygfsteel.com/keweibo/comments/144857.html</wfw:comment><comments>http://www.aygfsteel.com/keweibo/articles/144857.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/keweibo/comments/commentRss/144857.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/keweibo/services/trackbacks/144857.html</trackback:ping><description><![CDATA[<p>搞清常用~码Ҏ是解决字符集编码问题的基础。字W集~码的识别与转换、分析各Uؕ码生的原因、编E操作各U编码字W串Q例如字W数计算、截断处理){都需要弄清楚~码的特性?/p> <p>了解一U字W集~码主要是要了解该编码的~码范围Q编码对应的字符集(都包含哪些字W)Q和其他字符集编码之间的关系{?/p> <p><strong>ASCII</strong></p> <p>ASCII码是7位编码,~码范围?x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符L字符。其?x00-0x20?x7F?3个控制字W?/p> <p>只支持ASCII码的pȝ会忽略每个字节的最高位Q只认ؓ?位是有效位。HZ字符~码是早期Z在只支持7位ASCIIpȝ中传输中文而设计的~码。早期很多邮件系l也只支持ASCII~码Qؓ了传输中文邮件必M用BASE64或者其他编码方式?/p> <p><strong>GB2312</strong></p> <p>GB2312是基于区位码设计的,Z码把~码表分?4个区Q每个区对应94个位Q每个字W的区号和位L合v来就是该汉字的区位码。区位码一??0q制数来表示Q如1601pC?6?位,对应的字W是“?#8221;。在Z码的区号和位号上分别加上0xA0得CGB2312~码?/p> <p>Z码中01-09区是W号、数字区Q?6-87区是汉字区,10-15?8-94是未定义的空白区。它收录的汉字分成两Q第一U是常用汉字 ?755个,|于16-55区,按汉语拼韛_?WŞ序排列Q第二汉字是次常用汉字?008个,|于56-87区,按部?W画序排列。一U汉 字是按照拼音排序的,q个可以得到某个拼韛_一U汉字区位中的范_很多Ҏ汉字可以得到拼音的程序就是根据这个原理编写的?/p> <p>GB2312字符集中除常用简体汉字字W外q包括希腊字母、日文^假名及片假名字母、俄语西里尔字母{字W,未收录繁体中文汉字和一些生d。可以用J体汉字试某些pȝ是不是只支持GB2312~码?/p> <p>GB2312的编码范围是0xA1A1-0x7E7EQ去掉未定义的区域之后可以理解ؓ实际~码范围?xA1A1-0xF7FE?/p> <p>EUC-CN可以理解为GB2312的别名,和GB2312完全相同?/p> <blockquote> <p>Z码更应该认ؓ是字W集的定义,定义了所收录的字W和字符位置Q而GB2312及EUC-CN是实际计机环境中支持这 U字W集的编码。HZ和ISO-2022-CN是对应区位码字符集的另外两种~码Q都是用7位编码空间来支持汉字。区位码和GB2312~码的关pL点像 Unicode和UTF-8?/p> </blockquote> <p><strong>GBK</strong></p> <p>GBK~码是GB2312~码的超集,向下完全兼容GB2312Q同时GBK收录了Unicode基本多文U^面中的所有CJK汉字。同 GB2312一PGBK也支持希腊字母、日文假名字母、俄语字母等字符Q但不支持韩语中的表韛_W(非汉字字W)。GBKq收录了GB2312不包含的 汉字部首W号、竖排标点符L字符?/p> <p>GBK的整体编码范围是?x8140-0xFEFEQ不包括低字节是0×7F的组合。高字节范围?×81-0xFEQ低字节范围?x40-7E?x80-0xFE?/p> <p>低字节是0x40-0x7E的GBK字符有一定特D性,因ؓq些字符占用了ASCII码的位置Q这样会l一些系l带来麻烦?/p> <blockquote> <p>有些pȝ中用0x40-0x7E中的字符Q如“|”Q做ҎW号Q在定位q些W号时又没有判断q些W号是不是属于某?GBK字符的低字节Q这样就会造成错误判断。在支持GB2312的环境下׃存在q个问题。需要注意的是支持GBK的环境中于0x80的某个字节未必就 是ASCIIW号Q另外就是最好选用于0×40的ASCIIW号做一些特D符Pq样可以快速定位,且不用担心是某个汉字的另一半。Big5~码中也存在相应问题?/p> </blockquote> <p>CP936和GBK的有些许差别Q绝大多数情况下可以把CP936当作GBK的别名?/p> <p><strong>GB18030</strong></p> <p>GB18030~码向下兼容GBK和GB2312Q兼容的含义是不仅字W兼容,而且相同字符的编码也相同。GB18030收录了所有Unicode3.1中的字符Q包括中国少数民族字W,GBK不支持的韩文字符{等Q也可以说是世界大多民族的文字符号都被收录在内?/p> <p>GBK和GB2312都是双字节等宽编码,如果上和ASCII兼容所支持的单字节Q也可以理解为是单字节和双字节؜合的变长~码。GB18030~码是变长编码,有单字节、双字节和四字节三种方式?/p> <p>GB18030的单字节~码范围?x00-0x7FQ完全等同与ASCIIQ双字节~码的范围和GBK相同Q高字节?x81-0xFEQ低字节 的编码范围是0x40-0x7E?x80-FEQ四字节~码中第一、三字节的编码范围是0x81-0xFEQ二、四字节?x30-0x39?/p> <blockquote> <p>Windows中CP936代码?x80来表C欧元符P而在GB18030~码中没有?x80~码位,用其他位|来表示Ƨ元W号。这可以理解为是GB18030向下兼容性上的一点小问题Q也可以理解?x80是CP936对GBK的扩展,而GB18030只是和GBK兼容良好?/p> </blockquote> <img src ="http://www.aygfsteel.com/keweibo/aggbug/144857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/keweibo/" target="_blank">KE</a> 2007-09-13 15:00 <a href="http://www.aygfsteel.com/keweibo/articles/144857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">̩</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">û</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʻ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ˳</a>| <a href="http://" target="_blank">Ҿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̶</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">»</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ľ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Խ</a>| <a href="http://" target="_blank">¡</a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>