windows/linux服务器程序支持库的开发(1)--UCS-2与UTF8之间的选择(1)
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
总体计划见:
此为序篇。
作为常常在windows下开发的人员,一般将windows下的Unicode实现直接称为Unicode,(比如我在前面就一直是这样做的),而把其他的Unicode实现称为更加具体的名称,比如UTF-8,UTF-16等,但是既然这里要讨论各种Unicode的实现,所以,还是得好好的区分一下,这里,将windows下的Unicode实现正名为UTF-16,但是遗憾的是,我发现Windows下的字符串处理函数实际仅仅是支持UCS-2的(在Window XP下测试结果),所以从编程的角度来讲,我们还是只能使用UCS-2,见文章《确定Windows XP到底是UCS-2的还是UTF-16的》,所以,这里都不混淆的情况下都以UCS-2代替。
以一个字符对应一个Unicode编码,并且要表达全部的Unicode编码,连普通的两个字节的wchar_t都不够,所以,现在有了新的UTF-32,gcc中wchar_t也默认已经是32位的了,顺应的就是这种潮流,毕竟,在现在,硬盘内存都当白菜卖了,相对而言,不在乎那么点空间,最最重要的是编程方便,还有速度。
关于此部分内容参看《UTF-16/UCS-2》。
关于Unicode的编码范围的内容参看《Mapping of Unicode character planes》。
名字缩写注释:
通用字符集 (Universal Character Set, UCS)
统一码转换格式(Unicode Transformation Format,UTF)
假如初次接触,那么要了解清楚Unicode还不是那么简单的事情,这是实话。当年语言编码混乱的时代,一种语言的软件不能正常的在另外语言的操作系统上显示,编多语言的程序是件非常痛苦的事情,编写一个可以在不同操作系统上都显示正确字符的软件那是高难度的事情。当时呼吁统一编码的呼声很高,原以为Unicode一出,将来的程序员将是无比幸福,甚至都不会了解什么叫编码,什么叫代码页(Codepage),因为已经不用考虑了。
但是,事实是残酷的,当Unicode比较普及了以后,由于历史的原因,光是Unicode本身的实现的种类过多,导致的各个操作系统不兼容的问题,都能够让程序员苦恼痛苦不已,比如,现在要做的UTF-8与UCS-2之间的选择。可能无论哪个初学windows的人都会迷惑于其A,W的函数结尾,初学MFC编程的人都会为其中大量的_T()使用感到莫名奇妙,这些,其实都是历史原因,为了当时一代程序员的理想,用一套源码,实现ASCII和UCS-2两套编码兼容。
由于Windows的内核都已经是UTF-16化了,所以实际的开发中,即使不用到除英语以外的语言,使用Unicode其实都是有益的,起码对于现在的速度比内存更重要的时候,一般是有益的,因为使用UCS-2最多是字符多占用了一倍的内存,而使用ASCII实际是影响了所有字符串有关的API函数调用的速度。对于现实中几乎完全不可能去使用ASCII编译程序的中国程序员,还是按照老美们为了他们的习惯去规定的_T()模式,至今,我还感叹不已,毕竟,计算机的教育水平,国外和国内的话语权不是一个量级的,个人也是几乎看着“洋书”成长的,啃过英文原版技术书籍,而且哪怕是中文版的MSDN其实也是英文居多,所以,我们竟然会有这样符合老美们特殊国情的编程习惯-_-!
闲话少说,关于Unicode的起源发展,我在一篇《UTF-8和Unicode的FAQ》文档中见到过。这里是其英文版《UTF-8 and Unicode FAQ for Unix/Linux》。
在Unicode组织的官方主页上 http://unicode.org/ 的顶头,有这么一段话:
Welcome! The Unicode Consortium enables people around the world to use computers in any language. Our members develop the Unicode Standard, Unicode Locales (CLDR), and other standards. These specifications form the foundation for software internationalization in all major operating systems, search engines, applications, and the Web.
他们一点也不夸张,Unicode正是所有主要操作系统,搜索引擎,应用程序和网页的软件国际化的基础。这里我突然想起以前给lua for windows提交的那个库中的bug时,lua for windows的作者竟然回了两个中文字“关心”给我^^(虽然我不知道什么意思),见《真高兴啊。。。。实际的为开源事业做了点点贡献:),很久前指出的一个lua stdlib的bug得到确认》这在以前是不可想象的,因为在以前,英文的操作系统中要输出并显示个中文谈何容易啊。
这里我引用MS的话来说明一下Unicode的威力:
“采用支持 Unicode 的单源代码库使开发时间得以缩短,Unicode 为 Microsoft 带来的好处是显而易见的。就 Windows® 2000 来说,在发布英文产品后需要花费几个月的时间来准备其本地化版本。而对于 Windows XP,这一周期已缩短为几周时间。”—MS《通过 Unicode 5.0 将您的应用程序应用到全球》
这就是Unicode的威力,为程序员节省的时间是从几个月到几周这个量级。
候选的UTF-8/UCS-2
现在开发软件用Unicode,当然是没有疑问了。在windows下面直接用UCS-2估计也没有疑问。但是考虑的可移植的时候,问题就来了,目前Linux的内核Unicode实现都是UTF-8的,并且gcc新版的wchar_t已经是新标准的4字节了,这样就算同样的宽字符接口,可能也不一定和windows的wchar_t兼容,要用同一套代码可能还得设置-fshort-wchar的编译选项,看看这样的mannul说明,就知道这样做不是什么长久之计(我们公司一直这样做):
-fshort-wchar
Override the underlying type for wchar_t to be short unsigned int instead of the default for the target. This option is useful for building programs to run under WINE.
Warning: the -fshort-wchar switch causes GCC to generate code that is not inary compatible with code generated without that switch. Use it to conform to a non-default application binary interface.
这样个人感觉也不是什么长久之记,其实还不如用UTF8方便,用UTF8的坏处很明显,那就是处理的函数少一些,而且,字符的长度不一,不如UNICODE好处理。
这里真是个两难的选择,我需要好好研究研究,以后暂时遵循这个规则,之所以说暂时,原因很简单,我个人认为,将来UTF-32才是主流的编码方式,并且UTF-32也是以后唯一需要的编码方式。
UTF8:
优点:
1.UCS 字符 U+0000 到 U+007F (ASCII) 被编码为字节 0x00 到 0x7F (ASCII 兼容)。 这意味着只包含 7 位 ASCII 字符的文件在 ASCII 和 UTF-8 两种编码方式下是一样的。意味着完美兼容ASCII。--《UTF-8 and Unicode FAQ》
2.Linux的内核是UTF88的,意味着在Linux下使用UTF8有得天独厚的优势。而且不仅仅是Linux,大量的开源计划(由于大部分开源计划都是围绕着Linux走的),包括网页,XML等也都是原生UTF-8的,可参考源程序范例更多。
3.由于其单字节编码的方式,不用考虑大头小头的字节序问题。
4.以英文为主的数据在存储时,占用的空间较小。
缺点:
1. 大量的组合字符(即用两个以上字节来表示一个字符),使得字符串的处理很不方便。有着和任何变长编码一样的痛苦。并且因为这个原因,当字符超出ASCII范围时,原有的C/C++字符串函数运行结果都不会是你想要的。
2. 以非ASCII字符为主的数据在存储时,占用空间较大。
UCS-2:
优点:
1.统一定长编码,都是两个字节对应一个字符,所以对于字符串的处理非常方便。没有变长的痛苦。大量的宽字节C/C++函数都可以直接使用。
2.Windows的内核是UTF-16的,但是由于UCS-2仅仅是UTF-16的一个子集,所以在Windows下使用UCS-2,有得天独厚的优势。另外,从资料上看,使用UTF-16/UCS-2的操作系统阵营比使用UTF-8的更加庞大。见《UTF-16/UCS-2
》的“Use in major operating systems and environments”一节,带来的好处是,在与不同语言/平台的程序(毕竟我要写的是网络程序)进行通信时,会更加方便。
缺点:
1.在 Unix 下使用 UCS-2 (或 UCS-4) 会导致非常严重的问题. 用这些编码的字符串会包含一些特殊的字符, 比如 '/0' 或 '/', 它们在 文件名和其他 C 库函数参数里都有特别的含义. 另外, 大多数使用 ASCII 文件的 UNIX 下的工具, 如果不进行重大修改是无法读取 16 位的字符的. 基于这些原因, 在文件名, 文本文件, 环境变量等地方, UCS-2 不适合作为 Unicode 的外部编码. --《UTF-8 and Unicode FAQ》,实际其意思就是原有的C语言字符串函数将完全失效,哪怕你用的就是ASCII字符也是这样。
上述的比较仅仅是理论上的,并且似乎难决高下,以下将具体的分别在Linux,Windows不同的环境下尝试使用UCS-2和UTF-8,以做出决定。
大概会尝试的有:
C/C++ 中使用,Python中使用,Lua中使用,正则表达式的使用。
之所以花这么多时间来研究这个问题,出于很多原因,有人说,编程的主要时间是花在进行字符串的处理上了,而现在这样的选择,将会决定以后我大部分时间是否是会更长,还是更短,是更容易,还是更难的问题。而且,对程序的效率,空间占用,肯定也是有影响的。对于初学者来说,一般用ANSI学习就完了,到了真实的使用,这些问题的考虑,甚至比可以想象的还要重要。
对于这个话题,著名开源计划Samba的发起人Andrew Tridgell,曾经在为Samba适应Windows的UCS-2时,提出了一个移植计划,一步一步的将Samba的内核从UTF-8移植到UCS-2. 《utf8 vs ucs2》,颇有味道:)对于同样致力于跨平台程序编写的我,也是指导意义很多。毕竟作为一个不准备在Windows下运行,而是仅仅需要与Windows进行通行的一个程序,最后都需要将内核全面的UCS-2化,而我的程序是不仅仅是需要与Windows下程序通信,并且还需要能够在Windows下运行的,是不是更应该用UCS-2呢?有待研究。另外,我还找到了一个在UNIX/Linux下使用UCS-2的范例:)开源就是好啊。
而我公司使用的是UCS-2,主要是因为客户端是肯定跑在Windows下而且是肯定不需要跑到Linux下的,而作为网络游戏,自然以客户端的效率为主,所以服务器多了一下无谓的字符转换操作也接受了。
UCS-2还是UTF-8,需要继续研究...................................
参考:
UTF-8, UTF-16, UTF-32 & BOM
UTF-16/UCS-2
Unicode详解—想当棒的中文讲解
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
分享到:
相关推荐
UCS-2转换为UTF-8代码集完整版 UCS-2(Universal Character Set 2)是一种 Unicode 编码形式,用于表示 Unicode 字符。UTF-8(Unicode Transformation Format 8)是一种 Unicode 编码形式,用于将 Unicode 字符转换...
身份证读卡器生成的基本信息TEXT文件,由于是采用 GB 13000 的 UCS-2 编码格式,java读取出来是乱码,这个段代码就是解决转码问题的,亲测可用
SDL_iconv 用于转换字符编码的库。... UCS-2-INTERNAL UCS4 UCS-4 UCS-4LE UCS-4BE UCS-4-INTERNAL SDL_iconv.c是一部分。 我做了一些修改以构建没有完整SDL库的SDL_iconv.c。 许可下的许可。
### 四、UCS-2与UTF-8之间的转换关系 UCS-2是一种固定长度的编码方式,每个字符占用2个字节,适用于UCS中的基本多文种平面(BMP)中的字符。而UTF-8则是一种变长编码,根据UCS字符的不同,使用1到4个字节表示。两者...
详细描述UTF8和UCS2的 编码规则,并附带互相转换的c++源代码
总的来说,这个更新的C++ UTF-8库1.1版为开发者提供了强大的跨平台Unicode处理能力,无论是处理ASCII、UCS-2还是完整的UTF-8编码,都能游刃有余。对于需要处理多语言文本的应用,或者需要在Windows和Linux之间迁移...
发送中文短信,会用到UCS2编码,很多网友反应中文发送和接收乱码,这个烦恼可以解决了。 注意:要在系统配置里增加 LANG=zh_CN.GB18030 export LANG 语言配置不对,这个函数会出错的,另外,例子有点问题,换一个...
"GB2312, UTF8, UCS2汉字编码生成与转换工具"就是这样一个实用工具,它能够帮助用户方便地进行编码间的转换,确保信息在各种系统间准确无误地传递。 对于"release"这个文件,它可能是该工具的发行版本,可能包含了...
1. **检查字体资源**:确保你的项目或系统环境中已经包含了`STSongStd-Light`字体,并且该字体支持UniGB-UCS2-H编码。如果缺少这个字体,可以尝试将它添加到系统路径,或者在iText中明确指定字体资源。 2. **正确...
2. **字符编码转换**: 在VB中,进行UCS2与汉字之间的转换通常需要使用特定的函数或库。例如,可以使用`System.Text.Encoding`类来实现编码转换。首先,将汉字字符串转换为UCS2编码的字节数组,然后将UCS2字节数组...
### 多字节与UTF-8、Unicode之间的转换 在计算机科学领域,字符编码是将文字映射到二进制数据的一种方式。不同的字符编码方案适用于不同的应用场景。本篇文章主要探讨的是多字节(MBCS)编码与UTF-8、Unicode编码...
字符编码转换的工具(根据3GPP 03.38,11.11附录等协议),可以把字符转换成ascii,8 bit,7 bit,UCS2,UTF-8编码。 在做手机软件开发的时候,调试WMS,Phone book,STK等模块可能会用的到。
在Linux操作系统中,预览PDF文件可能不像在Windows或macOS那样直观,因为默认的桌面环境可能不包含内置的PDF查看器。然而,借助开源工具和技术,我们可以轻松地解决这个问题。这里我们将介绍一种方法,利用名为`...
反之亦然,如果你接收到的是UTF-8编码的文本,而你的系统或程序只支持GB2312,你就需要进行反向转换。 这个压缩包提供的程序包括了源代码、MAKEFILE和最终库,这意味着用户可以直接编译和运行该程序,无需额外开发...
4. **解析复杂性**:UTF-8的解析相对较复杂,因为需要识别字节序列以确定字符长度,而UNICODE的解析相对简单,每个字符都有固定的字节数(在UCS-2或UCS-4中)。 **四、UNICODE与UTF-8的转换** 1. **UNICODE到UTF-8...
`WideCharToUtf8` 和 `Utf8ToWideChar` 是C++Builder中的函数,用于UCS-2(或UTF-16)和UTF-8之间的转换。在VB中,可以使用PInvoke(Platform Invoke)技术调用这些API函数。 在实际应用中,如果需要在VB程序中实现...
在本文中,我们将深入探讨如何使用C语言实现SMS消息的编码和解码,特别是7-bit编码和解码,以及UCS2编码。首先,我们关注7-bit编码和解码算法。 7-bit编码是一种用于SMS(Short Message Service)的编码方式,它...
《UCS-2与Windows 8环境下的编码转换探索》 在信息技术领域,字符编码是数据处理中的一个重要环节,尤其在跨平台、多语言交互的环境中,正确的字符编码选择和转换至关重要。UCS-2是一种广泛使用的16位Unicode字符...
UCS-Satellite-Database-5-1-2022 UCS发布的全球卫星数据库,包含通信、导航、遥感等领域的卫星基本信息,数据截止到2022年5月1日,来源:https://www.ucsusa.org/resources/satellite-database
Unicode编码分为多种类型,如UCS-2、UCS-4等,其中UCS-2是最常用的,它使用两个字节来表示一个字符。在Java中,默认的字符串类型`String`就是基于Unicode编码的。 #### 2. ISO-8859-1 ISO-8859-1是一种单字节编码...