新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   >>中国XML论坛<<     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论SVG, GML, X3D, VRML, VML, XAML, AVALON, Batik等基于XML的图形技术,以及有关GIS的应用。
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - 高级XML应用『 SVG/GML/VRML/X3D/XAML 』 → UTF-8编码研究 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 12877 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: UTF-8编码研究 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 UTF-8编码研究

    ==========================================================
    相关的题外话:
    一、操作系统
    window系统内部都是unicode的。文件夹名,文件名等都是unicode的,任何语言系统下都能正常显示。
    二、输入法:
    微软拼音输出的是Unicode的,智能ABC输出是简体中文的(所以智能ABC在非简体中文系统根本不能用,只能打英文)。
    三、网页的textarea
    网页的textarea是用unicode显示的。所以往里打什么字都能显示。而一些flash做的输入框就不行了。
    四、Access2000
    [URL=http://www.office-cn.net/shop]access[/URL]里面保存的数据是unicode的,在任何语言系统下都能显示。
    如果数据视图查看有些字符不正常,那是因为显示所用的字体不是Unicode字体,
    换用Arial Unicode MS 字体就能全部显示了。([URL=http://www.office-cn.net/shop]access[/URL]帮助,搜索,输入unicode,有说明)
    五、Word
    word里的繁简转换,简体转换到繁体后,内码仍是简体中文的,其实只是简体中的繁体字。
    六、ASP内部是Unicode的,所有文本都是Unicode存储的。需要时转换到指定字符集。
    =======================================================
    首先说下结论:
    <%@ codepage=936%>简体中文
    <%@ codepage=950%>繁体中文
    <%@ codepage=65001%>UTF-8

    codepage指定了IIS按什么编码读取传递过来的串串(表单提交,地址栏传递等)。
    也指定了所有文本变量从Unicode转换到的编码,
    也就指定了从数据库取出的数据从Unicode转换到的编码。(注意这个,很重要。)

    关键字:
    读取:一个串串,按简体读取是一些字,按繁体读取是一些字,串串本身编码没有变。
    转换:系统主动的转换,比如从Unicode的“化”字到Big5的“化”字,内码变成Big5的。如果Big5没有对应的字,保留Unicode形式(&#xxxx;)

    简体中文:化六个结论
    Unicode16进制形式:化六个结论
    Unicode10进制形式:化六个结论

    下面是我推测出来的编码转换的过程:
    客户端:输入法Unicode--输入框unicode--从Unicode按charset转换到对应编码()--表单发送编码

    服务器端:IIS解开表单编码--按codepage指定编码读取--转换到对应的Unicode--可以用request("")读取了--进行一些处理--以Unicode编码保存到数据库

    服务器端:读取数据库的Unicode数据,转换到codepage指定编码---生成源代码--IE按charset读取显示。


    下面举例说明:
    例一:
    假设有三个asp页面,典型的留言页面:
    1.    write.asp 简单的输入表单,提交到add.asp。
    <META http-equiv="Content-Type" content="text/html; charset=big5">
    2.    add.asp 接收留言,保存到数据库
    <%@ codepage=936%>
    3.    read.asp 从数据库取得留言,显示。
    <%@ codepage=936%> charset=GB2312 或
    <%@ codepage=950%> charset=big5

    大家可以猜一猜,我在write.asp里用微软拼音输入法输入“化六个讨论”。最后在read.asp里会显示什么样?
    是不是晕了。让我们从头分析。

    [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121340207.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL]

    例二:
    把例一的add.asp的<%@ codepage=936%>改为<%@ codepage=950%>,又会怎么样呢?

    [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121346501.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL]

    到这里发现了什么?
    1.如果输入的文字和Charset对应的不同,一转换,就可能出现Unicode形式的字了。这里就是原因所在。以后整个过程都保留着。
    2.Add.asp里codepage决定了保存到数据库的文字,用的是哪个语言对应的Unicode.如codepage=936,
    那么数据库保存的就是简体中文的Unicode(数据库拿回简体中文系统,一切正常的),
    codepage=950保存的就是繁体中文的Unicode.(拿回简体中文系统,就不对了)。
    3.注意一下串串的变化过程:
    --------------------------------------------------------------------
    1)    输入法---Charset    Unicode----指定字符集的映射
    2)    Charset----表单编码    串串简单编码
    3)    表单解码    上步的逆过程,两步抵消了。
    4)    串串à按codepage读取    串串没变,这步有可能“误会读取”
    5)    转为对应的Unicode    Codepage指定字符集----Unicode映射
    6)    中间处理,进数据库    无变化,直接以Unicode形式进入
    7)        
    8)    按codepage读取数据库     Unicode----codepage指定字符集的映射
    9)    显示,按Charset指定字符集读取    串串没变。
    -------------------------------------------------------------------------------
    以例一说明:
    [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121346861.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL]

    例二:
    [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121346210.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL]

    =============================================
    晕了。现在来用用知识。

    案例1。
    简体中文系统下跑的好好的代码,放到国外空间上,数据库里乱码,原有的数据也乱码。
    分析:因为大多数人平时用的都是简体中文系统,默认的codepage=936,所以平时大家不写也没有关系。
    但到了国外空间问题就出来了。从数据库里的Unicode转换到英文编码去了,所以数据库原有的简体中文转换到英文后,按GB显示自然乱码。
    如图,新输入的文字显示正常,但数据库里保存的是英文的Unicode的。
    解决方法:全部加上<%@codepage=936即可%>。
    全程只有简体中文与对应Unicode间的转换。

    [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121346593.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL]

    案例二:
    简体中文的代码和数据,想转为完全的繁体版,该怎么办?
    分析:1。代码文件编码全部改为Big5的,文件本身保存编码选繁体。
    2.<%@ codepage=936 %>
    3.Charset=big5
    4.[URL=http://www.office-cn.net/shop]access[/URL]版本无所谓,因为[URL=http://www.office-cn.net/shop]access[/URL]里的数据是Unicode的。
    5.好了,代码可以在纯繁体系统下跑了。
    6.遗留问题:原有的简体中文数据读出会有一些问号。效果同例一的950读取,big5显示。因为从简体中文的Unicode转换到繁体中文了,有些字繁体中没有,就会出问号。
    7.解决:用一个临时asp页,codepage=65001,读出为简体中文的Unicode,用一个Unicode->Big5的函数,转为繁体中文,然后写回数据库,应该行了吧?
    案例三:
    简体中文的代码和数据库,想转为完全的UTF-8版,怎么办?
    分析:1。代码文件编码全部改为UTF-8的,文件本身保存编码选UTF8。
    2.<%@ codepage=65001 %>
    3.Charset=UTF-8
    4.[URL=http://www.office-cn.net/shop]access[/URL]版本无所谓,因为[URL=http://www.office-cn.net/shop]access[/URL]里的数据是Unicode的。
    5.OK,没有任何遗留问题。原有的简体中文也会正常显示。因为数据库里是Unicode的,按Unicode读出没有任何转换。自然不会乱码。看来转到UTF-8还是很简单的。
    =============================================
    案例完全是我按照理论推导出来了,未经证实。
    有类似经历的欢迎批评指正。

    文件保存编码和codepage之间的关系

    结论:
    codepage指定了IIS按什么编码读取源文件。如果codepage和源文件的实际编码相同,则读取正确,否则就会乱码。有时还会报编译错误,大概意思是无效字符吧。

    题外话:
    1.一个文件保存格式为GB2312,那么你在编辑的时候,不论是用输入法输入的,还是copy粘贴的,所有的字都会转为GB2312编码。
    2.象Mid,Left,Chr,Instr等函数都是面向Unicode形式变量的,他们的入口和出口参数都是unicode形式的,也就是说,进入时从Unicode转为对应编码,出来时转回Unicode。

    试验过程:
    假设文件a.asp,保存编码格式为GB2312,输入:帳票マッ(日文输入法输入),自动变为GB2312编码的,但因为GB2312字库中有日文,所以显示正常。
    上面四个字如果按日文Shift-JIS编码查看,则是: [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121346593.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL](图片,否则后面三个是空白)。

    --A--
    .asp中有代码:
    ---------------------
    <%@codepage=936%>
    aa="帳票マッ"
    response.write aa
    -------------------------
    输出结果,按charset=GB2312查看为:帳票マッ
    按charset=Shift-JIS查看为: [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121346593.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL]
    如果codepage=932,输出按charset=GB2312查看为:帳票マッ
    按charset=Shift-JIS查看为: [URL=http://www.office-cn.net/Article/UploadFiles/200504/20050420121346593.gif]按此在新窗口浏览图片document.body.clientWidth-300) {this.height=(document.body.clientWidth-300)*this.height/this.width;this.width=document.body.clientWidth-300}" border=0>[/URL]

    过程分析:IIS编译器按936简体中文读取源文件,把“帳票マッ”转为对应的Unicode编码,赋值给变量aa,也就是说LenB(aa)=8。
    Response.write输出的时候,从Unicode形式转换到对应的936简体中文编码,输出为html,发送给浏览器,浏览器按charset显示。

    --B--
    如果把文件的保存编码换为Shift-JIS,注意四个文字要重新输入。保存的是Shift-JIS编码。
    <% @codepage=936 %>输出结果,
    按charset=GB2312查看为:挔昜儅僢
    按shift-jis查看为:帳票マッ
    <% @codepage=932 %>输出结果,
    按charset=GB2312查看为:挔昜儅僢
    按shift-jis查看为:帳票マッ

    总结:
    GB—按GB读取—对应的Unicode—转回GB—按GB2312查看,正常。
    GB—按GB读取—对应的Unicode—转回GB—按Shift-JIS查看,不正常。
    GB—按Shift-JIS读取—对应的Unicode—转回Shift-JIS—按GB2312查看,正常。
    GB—按Shift-JIS读取—对应的Unicode—转回Shift-JIS—按Shift-JIS查看,不正常。

    Shift-JIS---按GB读取—对应的Unicode---转回GB—按GB2312查看,不正常。
    Shift-JIS---按GB读取—对应的Unicode---转回GB—按Shift-JIS查看,正常。
    Shift-JIS---按Shift-JIS读取—对应的Unicode---转回Shift-JIS—按GB2312查看,不正常。
    Shift-JIS---按Shift-JIS读取—对应的Unicode---转回Shift-JIS—按Shift-JIS查看,正常。

    可以看出,ASP中的处理是对称的,所以对于直接输出和简单处理的文字,codepage设置为什么都没有影响,只要文件的编码和最终显示的charset相同,那么就会正常显示。


    不会出现乱码。
    因为简体中文字库>繁体字库,所以繁体转换到简体时,总是能找到对应的字,
    程序接收的已经是简体Unicode的了,数据库里的数据都不会乱码,后面读取显示自然没有问题。
    ==============================
    而如果是繁体的代码,charset=big5的话,输入简体中文,就有出现乱码的可能。
    因为简体-->繁体的转换,就可能没有字对应。
    ========================================
    陈桥输出的繁体字是纯繁体内码的吧?
    如果是,那么数据库里应该是对应的简体字的,
    输入简体字检索应该可以检索到的。
    ====================
    你先都加上codepage看看吧。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/2/7 8:56:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    UTF-8 字符集基础
    字符集简史
    在所有字符集中,最知名可能要数被称为ASCII的7位字符集了。它是美国信息交换标准委员会(American Standards Committee for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(退格、响铃等)组成。


    但是,由于他是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。其中有一种通常被成为IBM字符集,它把值为128-255之间的字符用于画图和画线,以及一些特殊的欧洲字符。另一种8位字符集是ISO 8859-1 Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,也因此而得名。


    欧洲语言不是地球上的唯一语言,因此亚洲和非洲语言并不能被8位字符集所支持。仅汉语(或pictograms)字母表就有80000以上个字符。但是把汉语、日语和越南语的一些相似的字符结合起来,在不同的语言里,使不同的字符代表不同的字,这样只用2个字节就可以编码地球上几乎所有地区的文字。因此,创建了UNICODE编码。它通过增加一个高字节对ISO Latin-1字符集进行扩展,当这些高字节位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚像形汉字和韩国像形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic, Khmer, Mongolian, Hmong, Tai Lu, Tai Mau文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform, Balti, Brahmi, Etruscan, Hittite, Javanese, Numidian, Old Persian Cuneiform, Syrian之类的古老的文字。


    事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,既UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-7.5, UTF-8, UTF-16, 以及 UTF-32。本文讨论UTF-8字符集的基础。


    UTF_8字符集


    UTF-8是UNICODE的一种变长字符编码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码UNICODE字符。如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。


    UFT-8转换表表示如下:


    UNICODE UTF-8
    00000000 - 0000007F 0xxxxxxx
    00000080 - 000007FF 110xxxxx 10xxxxxx
    00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
    00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

    实际表示ASCII字符的UNICODE字符,将会编码成1个字节,并且UTF-8表示与ASCII字符表示是一样的。所有其他的UNCODE字符转化成UTF-8将需要至少2个字节。每个字节由一个换码序列开始。第一个字节由唯一的换码序列,由n位1加一位0组成。n位1表示字符编码所需的字节数。


    示例


    UNICODE uCA(11001010) 编码成UTF-8将需要2个字节:


    uCA -> C3 8A

    1100 1010
    110xxxxx 10xxxxxx

    1100 1010 -> 110xxxxx 10xxxxxx
    -> 110xxxxx 10xxxxx0
    -> 110xxxxx 10xxxx10
    -> 110xxxxx 10xxx010
    -> 110xxxxx 10xx1010
    -> 110xxxxx 10x01010
    -> 110xxxxx 10001010
    -> 110xxxx1 10001010
    -> 110xxx11 10001010
    -> 11000011 10001010
    -> C3 8A

    UNICODE uF03F (11110000 00111111) 编码成UTF-8将需要3个字节:


    u F03F -> EF 80 BF


    1111 0000 0011 1111 -> 1110xxxx 10xxxxxx 10xxxxxx
    -> 11101111 10000000 10111111
    -> EF 80 BF


    译者注:由上分析可以看到,UNCODE到UTF-8的转换就是先确定编码所需要的字节数,然后用UNICODE编码位从低位到高位依次填入上面表示为x的位上,不足的高位以0补充。以上是个人经验,如有错误,请不惜指教,谢过先:)


    UTF-8编码的优点:


    UTF-8编码可以通过屏蔽位和移位操作快速读写。
    字符串比较时strcmp()和wcscmp()的返回结果相同,因此使排序变得更加容易。
    字节FF和FE在UTF-8编码中永远不会出现,因此他们可以用来表明UTF-16或UTF-32文本(见BOM)
    UTF-8 是字节顺序无关的。它的字节顺序在所有系统中都是一样的,因此它实际上并不需要BOM。


    UTF-8编码的缺点:


    你无法从UNICODE字符数判断出UTF-8文本的字节数,因为UTF-8是一种变长编码
    它需要用2个字节编码那些用扩展ASCII字符集只需1个字节的字符
    ISO Latin-1 是UNICODE的子集,但不是UTF-8的子集
    8位字符的UTF-8编码会被email网关过滤,因为internet信息最初设计为7为ASCII码。因此产生了UTF-7编码。
    UTF-8 在它的表示中使用值100xxxxx的几率超过50%, 而现存的实现如ISO 2022, 4873, 6429, 和8859系统,会把它错认为是C1 控制码。因此产生了UTF-7.5编码。


    修正的UTF-8:


    java使用UTF-16表示内部文本,并支持用于字符串串行化的非标准的修正UTF-8编码。标准UTF-8和修正的UTF-8有两点不同:
    修正的UTF-8中,null字符编码成2个字节(11000000 00000000) 而不是标准的1个字节(00000000),这样作可以保证编码后的字符串中不会嵌入null字符。因此如果在类C语言中处理字符串,文本不会在第一个null字符时截断(C字符串以null结尾)。
    在标准UTF-8编码中,超出基本多语言范围(BMP - Basic Multilingual Plain)的字符被编码为4字节格式,但是在修正的UTF-8编码中,他们由代理编码对(surrogate pairs)表示,然后这些代理编码对在序列中分别重新编码。结果标准UTF-8编码中需要4个字节的字符,在修正后的UTF-8编码中将需要6个字节。


    位序标志BOM


    BOM(Byte Order Mark)是一个字符,它表明UNICODE文本的UTF-16,UTF-32的编码字节顺序(高字节低字节顺序)和编码方式(UTF-8,UTF-16,UTF-32, 其中UTF-8编码是字节顺序无关的)。


    如下所示:


    Encoding Representation
    UTF-8 EF BB BF
    UTF-16 Big Endian FE FF
    UTF-16 Little Endian FF FE
    UTF-32 Big Endian 00 00 FE FF
    UTF-32 Little Endian FF FE 00 00


    UTF-8 C++ 程序编码示例:


    下面是四个C++函数,他们分别实现2字节和4字节UNICODE和UTF-8之间的转换。


    #define MASKBITS 0x3F
    #define MASKBYTE 0x80
    #define MASK2BYTES 0xC0
    #define MASK3BYTES 0xE0
    #define MASK4BYTES 0xF0
    #define MASK5BYTES 0xF8
    #define MASK6BYTES 0xFC

    typedef unsigned short Unicode2Bytes;
    typedef unsigned int Unicode4Bytes;

    void UTF8Encode2BytesUnicode(std::vector< Unicode2Bytes > input,
    std::vector< byte >& output)
    {
    for(int i=0; i < input.size(); i++)
    {
    // 0xxxxxxx
    if(input[i] < 0x80)
    {
    output.push_back((byte)input[i]);
    }
    // 110xxxxx 10xxxxxx
    else if(input[i] < 0x800)
    {
    output.push_back((byte)(MASK2BYTES | input[i] >> 6));
    output.push_back((byte)(MASKBYTE | input[i] & MASKBITS));
    }
    // 1110xxxx 10xxxxxx 10xxxxxx
    else if(input[i] < 0x10000)
    {
    output.push_back((byte)(MASK3BYTES | input[i] >> 12));
    output.push_back((byte)(MASKBYTE | input[i] >> 6 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] & MASKBITS));
    }
    }
    }

    void UTF8Decode2BytesUnicode(std::vector< byte > input,
    std::vector< Unicode2Bytes >& output)
    {
    for(int i=0; i < input.size();)
    {
    Unicode2Bytes ch;

    // 1110xxxx 10xxxxxx 10xxxxxx
    if((input[i] & MASK3BYTES) == MASK3BYTES)
    {
    ch = ((input[i] & 0x0F) << 12) | (
    (input[i+1] & MASKBITS) << 6)
    | (input[i+2] & MASKBITS);
    i += 3;
    }
    // 110xxxxx 10xxxxxx
    else if((input[i] & MASK2BYTES) == MASK2BYTES)
    {
    ch = ((input[i] & 0x1F) << 6) | (input[i+1] & MASKBITS);
    i += 2;
    }
    // 0xxxxxxx
    else if(input[i] < MASKBYTE)
    {
    ch = input[i];
    i += 1;
    }

    output.push_back(ch);
    }
    }

    void UTF8Encode4BytesUnicode(std::vector< Unicode4Bytes > input,
    std::vector< byte >& output)
    {
    for(int i=0; i < input.size(); i++)
    {
    // 0xxxxxxx
    if(input[i] < 0x80)
    {
    output.push_back((byte)input[i]);
    }
    // 110xxxxx 10xxxxxx
    else if(input[i] < 0x800)
    {
    output.push_back((byte)(MASK2BYTES | input[i] > 6));
    output.push_back((byte)(MASKBYTE | input[i] & MASKBITS));
    }
    // 1110xxxx 10xxxxxx 10xxxxxx
    else if(input[i] < 0x10000)
    {
    output.push_back((byte)(MASK3BYTES | input[i] >> 12));
    output.push_back((byte)(MASKBYTE | input[i] >> 6 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] & MASKBITS));
    }
    // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    else if(input[i] < 0x200000)
    {
    output.push_back((byte)(MASK4BYTES | input[i] >> 18));
    output.push_back((byte)(MASKBYTE | input[i] >> 12 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] >> 6 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] & MASKBITS));
    }
    // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    else if(input[i] < 0x4000000)
    {
    output.push_back((byte)(MASK5BYTES | input[i] >> 24));
    output.push_back((byte)(MASKBYTE | input[i] >> 18 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] >> 12 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] >> 6 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] & MASKBITS));
    }
    // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    else if(input[i] < 0x8000000)
    {
    output.push_back((byte)(MASK6BYTES | input[i] >> 30));
    output.push_back((byte)(MASKBYTE | input[i] >> 18 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] >> 12 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] >> 6 & MASKBITS));
    output.push_back((byte)(MASKBYTE | input[i] & MASKBITS));
    }
    }
    }

    void UTF8Decode4BytesUnicode(std::vector< byte > input,
    std::vector< Unicode4Bytes >& output)
    {
    for(int i=0; i < input.size();)
    {
    Unicode4Bytes ch;

    // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    if((input[i] & MASK6BYTES) == MASK6BYTES)
    {
    ch = ((input[i] & 0x01) << 30) | ((input[i+1] & MASKBITS) << 24)
    | ((input[i+2] & MASKBITS) << 18) | ((input[i+3]
    & MASKBITS) << 12)
    | ((input[i+4] & MASKBITS) << 6) | (input[i+5] & MASKBITS);
    i += 6;
    }
    // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    else if((input[i] & MASK5BYTES) == MASK5BYTES)
    {
    ch = ((input[i] & 0x03) << 24) | ((input[i+1]
    & MASKBITS) << 18)
    | ((input[i+2] & MASKBITS) << 12) | ((input[i+3]
    & MASKBITS) << 6)
    | (input[i+4] & MASKBITS);
    i += 5;
    }
    // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    else if((input[i] & MASK4BYTES) == MASK4BYTES)
    {
    ch = ((input[i] & 0x07) << 18) | ((input[i+1]
    & MASKBITS) << 12)
    | ((input[i+2] & MASKBITS) << 6) | (input[i+3] & MASKBITS);
    i += 4;
    }
    // 1110xxxx 10xxxxxx 10xxxxxx
    else if((input[i] & MASK3BYTES) == MASK3BYTES)
    {
    ch = ((input[i] & 0x0F) << 12) | ((input[i+1] & MASKBITS) << 6)
    | (input[i+2] & MASKBITS);
    i += 3;
    }
    // 110xxxxx 10xxxxxx
    else if((input[i] & MASK2BYTES) == MASK2BYTES)
    {
    ch = ((input[i] & 0x1F) << 6) | (input[i+1] & MASKBITS);
    i += 2;
    }
    // 0xxxxxxx
    else if(input[i] < MASKBYTE)
    {
    ch = input[i];
    i += 1;
    }
    output.push_back(ch);
    }
    }

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/2/7 8:58:00
     
     mumueyes 美女呀,离线,快来找我吧!
      
      
      等级:大一新生
      文章:3
      积分:71
      门派:XML.ORG.CN
      注册:2006/1/19

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给mumueyes发送一个短消息 把mumueyes加入好友 查看mumueyes的个人资料 搜索mumueyes在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看mumueyes的博客3
    发贴心情 
    一直对编码不太明白,荡回去好好研究,谢谢!
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/2/8 21:52:00
     
     lajfox 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:3
      积分:67
      门派:XML.ORG.CN
      注册:2006/3/9

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给lajfox发送一个短消息 把lajfox加入好友 查看lajfox的个人资料 搜索lajfox在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看lajfox的博客4
    发贴心情 
    不错,楼主是有心人啊.
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/3/9 15:47:00
     
     wenwu2008 帅哥哟,离线,有人找我吗?巨蟹座1985-7-9
      
      
      等级:大二(研究C++)
      文章:28
      积分:290
      门派:XML.ORG.CN
      注册:2006/4/4

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给wenwu2008发送一个短消息 把wenwu2008加入好友 查看wenwu2008的个人资料 搜索wenwu2008在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 点击这里发送电邮给wenwu2008 引用回复这个贴子 回复这个贴子 查看wenwu2008的博客5
    发贴心情 
    谢谢楼主

    ----------------------------------------------
    人在夕阳黄昏后,陪着明月等寂寞!

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/4/10 10:41:00
     
     wanghai00 帅哥哟,离线,有人找我吗?魔羯座2000-12-31
      
      
      威望:4
      等级:大四(总算啃完XML规范了)
      文章:108
      积分:1085
      门派:XML.ORG.CN
      注册:2005/10/1

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给wanghai00发送一个短消息 把wanghai00加入好友 查看wanghai00的个人资料 搜索wanghai00在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 点击这里发送电邮给wanghai00  访问wanghai00的主页 引用回复这个贴子 回复这个贴子 查看wanghai00的博客6
    发贴心情 
    谢谢老大,前几天还为编码发愁呢,看到这篇文章,似乎有点明白。

    ----------------------------------------------
    交流提高呀!

    svg技术交流: 
    http://greaterthanme.blog.hexun.com/list.aspx?
    tag=svg
    svg技术交流群:24785607
    svg文件共享邮箱:svgcn@126.com  
    password:svg.net.cn

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/4/10 21:58:00
     
     babo021 帅哥哟,离线,有人找我吗?
      
      
      等级:大一(高数修炼中)
      文章:17
      积分:131
      门派:XML.ORG.CN
      注册:2005/11/11

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给babo021发送一个短消息 把babo021加入好友 查看babo021的个人资料 搜索babo021在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看babo021的博客7
    发贴心情 
    以下是引用lajfox在2006-3-9 15:47:00的发言:
    不错,楼主是有心人啊.

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/5/17 12:10:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/10/6 3:27:13

    本主题贴数7,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    122.070ms