`
totoxian
  • 浏览: 1075744 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

让你的软件支持繁体中文

阅读更多

让你的软件支持繁体中文

中国台湾、香港的汉字用的是BIG5编码,而大陆的汉字用的是GB编码(GB2312也好,GBK也好),简体中文软件直接拿到繁体中文环境下运行,问题就出来了。

怎么办呢?

我们的软件是一款用C#.NET+ASP.NET开发的,所谓B/S型的软件,客户端只须用浏览器访问我们的服务器就行了。很自然的就想到,把代码中的所有的简体字都转换成繁体字,问题不就解决了吗?

说干就干。从网上找来了一款转换工具将全部代码文件转换了一遍。编译后运行,发觉静态的文字或提示信息确实已经变成了繁体,但从数据库中拿出来的还是简体(乱码),转换后的各种配置文件也读取出错(因为程序仍然按GB编码的格式进行读取)。还有一个问题,就是源代码只能转换一次。因为第一次转换后GB变成了BIG5,如果再转,就是BIG5BIG5,结果变得不可辨认。由于源文件非常多,修改维护起来非常麻烦。

看来这种方法不可行。

那么能不能给我们的软件加上自适应的功能,增加对繁体中文的支持呢?

ASP.NET中,页面Page有个对象Response,该对象将 HTTP 响应数据发送到客户端,而Response有个获取或设置包装筛选器对象的属性Filter,用于在传输之前修改 HTTP 实体主体。当创建 Stream 对象并将 Response.Filter 属性设置为 Stream 对象时,所有由 Response.Write 发送的 HTTP 输出将通过筛选器。只要我们重载Stream类,在Stream类的Write()方法中将GB码转换成BIG5码,然后将Response.Filter = 重载Stream类,就可以达到在信息输出到客户端前先转换的效果。

//页面装载事件

private void Page_Load(object sender, System.EventArgs e)

{

// 在此处放置用户代码以初始化页面

Response.Filter = new CG2BFilter(Response.Filter);//设置筛选器

Response.Charset = “big5”;

……

}

简体转为繁体类CG2BFilter

public class CG2BFilter : Stream

{

……

//重载函数Write

public override void Write(byte[] buffer, int offset, int count)

{

WriteGB2BIG(buffer, offset, count);

}

//简体转为繁体

private void WriteGB2BIG(byte[] buffer, int offset, int count)

{

if( count == 0 )

{

return;

}

//936是简体中文代码页编号

Encoding e = Encoding.GetEncoding(936);

string str = e.GetString(buffer,offset,count);

//有些简体字没有对应的Big5,所以需要先转换成繁体的GB,再进行转换 for( int i=0;i<str.Length;i++ )

{

//_SGB是部分GB2312简体中文字库,_tGB则是对应的GB2312繁体字库

int j = _sGB.IndexOf(str[i]);

if( j != -1 )

{

str = str.Replace(_sGB[j],_tGB[j]);

}

}

//950BIG5码代码页编号

e = Encoding.GetEncoding(950);

_sink.Write(e.GetBytes(str),0,e.GetByteCount(str));

}

……

}

这样写,是建立在待转换的流全部都是GB编码的基础上的,而大多数情况下也没有什么问题,不过,如果一个页面存在表单控件且控件内有汉字内容随同输出时,那么该页面在运行过程中有回传等刷新动作的话,就可能出现乱码。究其原因,是因为在页面第一次打开时,控件值由简体转成了繁体,回传的时候,则传回服务器的这部分控件值也为繁体。接着再输出,问题就来了:控件值为繁体,而页面本身还是简体,也就是说,输出流中存在混合编码,这样还一刀切将它们认为全是GB编码来加以转换就不行了,要加以区别。

怎么区别呢?BIG5GB有什么区别吗?很遗憾,并没有什么明显的区别,也就是说,给你一个汉字编码,很难判断它究竟是GB还是BIG5。一般倾向于认为低字节在0x40~0x7F范围的就是BIG5码,因为没有简体字的低字节在这个范围。不过要注意,GB编码也有繁体字,并且这些繁体字的低字节也有位于0x40~0x7F的。所以这招并非万灵丹。

将数值从高字节0x81~0xFF,低字节0x40~0xFF这样组合输出到页面,如下:

string str = "";

Encoding gbe = Encoding.GetEncoding(936);

byte[] buffer = {0,0};

for( byte y = 0x81;y<0xFF;y++ )

{//高字节

str += "<br>";

for( byte x = 0x40;x<0xFF;x++ )

{//低字节

buffer[0] = y;

buffer[1] = x;

//以红色输出汉字,并注明其高低字节值

str += "&nbsp;0x" + y.ToString("X") + x.ToString("X") + "<font color=\"red\" size=4>" + gbe.GetString(buffer) + "</font>";

}

}

Response.Write(str);

然后在浏览器里分别用GB编码和BIG5编码观察,你会发现,这两种编码中,都存在着有些字节值并没有相应的汉字,而是一些奇怪的符号、问号甚至是空白。于是可以这样认为:如果一个汉字的字节值在某种编码中找不到汉字,则说明它不属于这种编码。经过认真比较归纳,两种编码都划定了一些范围,然后可以逐个考察输出流中的汉字,看它是否落在该范围,以此判定它属于何种编码。

虽然划定了一些范围,但GBBIG5重叠的区域实在太多,有许多字用两种编码去套,好象都可以,逐个字转换,误差很大。后来发现了一个很重要的思想,就是:在混合汉字编码的流中,不同的汉字编码总是不相邻的,它们中间有西文字符隔开(因为网页中,控件值都包含在许多HTML标记之间),也就是说,如果有一个汉字确定是某种编码,则可以推断与它相邻的所有汉字都属于同一种编码。事实证明,这种思想使得转换的准确性得到大幅度的提高。

修正后的类CG2Bfilter

public class CG2BFilter : Stream

{

……

public override void Write(byte[] buffer, int offset, int count)

{

int p = offset;

int q = p;

int limit = offset + count;

//这里定义了两个看似互相矛盾的布尔量:maybeBignotBig,主要是让它们配合使用。maybeBig表明一段流中出现了有Big5编码特征的汉字,因此可能是大五码但不能肯定,而notBig表明一段流出现了不可能是Big5编码的汉字,则这段流肯定不是大五码。一段流只有在maybeBig为真,且notBig为假时才可能认为它是大五码。

bool maybeBig = false;

bool notBig = false;

bool isChinese = false;

while( p < limit )

{

if( buffer[p] >= 0x81 && buffer[p] <= 0xFE )

{//汉字

if( !isChinese )

{//此前不是汉字,先输出

WriteAscii(buffer,q,p-1-q+1);// 待处理的流是西文字符 isChinese = true;

q = p;

}

p++;

if( p >= limit )

{

break;

}

if( buffer[p] >= 0x40 && buffer[p] <= 0x7E

|| buffer[p-1] >= 0xA1 && buffer[p-1] <= 0xA3 && buffer[p] >= 0x40 && buffer[p] <= 0xA0

|| buffer[p-1] >= 0xA4 && buffer[p-1] <= 0xA9

|| ( buffer[p-1] >= 0xAA && buffer[p-1] <= 0xAF || buffer[p-1] >= 0xF8 && buffer[p-1] <= 0xFD ) && buffer[p] >= 0xA1 && buffer[p] <= 0xFE )

{//很可能是BIG5,由此可以推断,这相邻的汉字串都可能是BIG5

maybeBig = true;

}

if( buffer[p] >= 0x7F && buffer[p] <= 0xA0

|| buffer[p-1] >= 0x81 && buffer[p-1] <= 0xA0

|| buffer[p-1] == 0xC6 && buffer[p] >= 0x7F && buffer[p] <= 0x0FE

|| buffer[p-1] >= 0xC7 && buffer[p-1] <= 0xC8

|| buffer[p-1] == 0xF9 && buffer[p] >= 0xDC

|| buffer[p-1] >= 0xFA )

{//肯定不是BIG,因为在此区间,BIG为空

notBig = true;

maybeBig = false;

}

}

else

{//非汉字

if( isChinese )

{//此前是汉字,先输出

if( maybeBig && !notBig)

{

WriteBIG(buffer,q,p-1-q+1);//待处理的流是BIG5

}

else

{//不肯定是繁体

WriteGB2BIG(buffer,q,p-1-q+1);// 待处理的流是GB

}

isChinese = false;

maybeBig = false;

notBig = false;

q = p;

}

}

p++;

}

//while语句最后一轮循环未处理的部分在这里处理

if( isChinese )

{

if( maybeBig && !notBig )

{

WriteBIG(buffer,q,p-1-q+1);

}

else

{

WriteGB2BIG(buffer,q,p-1-q+1);

}

}

else

{

WriteAscii(buffer,q,p-1-q+1);

}

}

//处理对象为GB

private void WriteGB2BIG(byte[] buffer, int offset, int count){……}

//处理对象为BIG5

private void WriteBIG(byte[] buffer, int offset, int count){……}

//处理对象为ASCII

private void WriteAscii(byte[] buffer, int offset, int count){……}

……

}

应用修正过的类后,浏览器用BIG5编码浏览运行我们的软件,效果令人非常满意,几乎看不到什么乱码,已经达到了实用的效果。不过繁简切换是一个相当复杂的问题,并不是仅仅是简单地将简体字转换成繁体字就行了,有时还涉及到语义的问题。比如,简体中文中,不论“发展”的“发”还是“头发”的“发”都是同一个字,而在繁体中,它们是不同的两个字。这部分已经超出了笔者现有的水平,不在考虑之列了。

分享到:
评论

相关推荐

    安装日文或繁体中文游戏用的一个软件

    在电脑上安装日文或繁体中文版的游戏时,可能会遇到一些语言环境的困扰,因为不是所有的操作系统都默认支持这些语言。此时,就需要借助特定的软件来创建合适的环境,以便顺利进行安装和运行。"安装日文或繁体中文...

    viavoice 繁体中文识别.rar

    Viavoice 繁体中文识别是一款专为繁体中文用户设计的高级语音识别软件,它将语音转化为文字,实现了人机交互的新高度。在当今信息化社会,语音识别技术正逐渐成为提升工作效率、便利生活的重要工具,而Viavoice的...

    简体字繁体字转换软件

    标题中的"简体字繁体字转换软件"指的是能够实现简体中文与繁体中文之间无缝切换的应用程序,它可以帮助用户在简体和繁体字之间进行快速、准确的转换。 简体字是中国大陆地区普遍使用的汉字形式,而繁体字则在台湾、...

    最著名的网络终端软件之一,现在它完全支持简体和繁体版Windows9x//NT,而且支持在英文版Windows上使用含中文多种语种可供选择。

    在Windows 9x/NT的时代,许多软件对中文的支持并不完善,而Nettern的出现打破了这一局面。它不仅内置了中文语言包,还支持第三方的中文输入法,如RichWin和Unionway,使得中文用户在使用过程中无需担心输入问题,极...

    win7系统64位语言包Chinese Traditional繁体中文

    **Windows 7 64位操作系统中的语言包安装与...此外,某些第三方软件可能不支持非英文环境,所以在切换语言前,确认你的应用程序是否兼容繁体中文环境。如果遇到任何问题,可以查阅微软官方帮助文档或寻求专业技术支持。

    汉字笔画数查询,简体汉字笔画查软件,繁体笔画数查询器

    汉字笔画数查询工具是IT领域中一种实用的软件应用,尤其对于学习中文、研究汉字或者进行汉字输入法开发的人员来说,具有重要的价值。它能够帮助用户快速准确地了解汉字的笔画数量,无论是简体汉字还是繁体汉字,都能...

    IE繁体字库在IE中显示BIG5码繁体汉字

    标题中的“IE繁体字库在IE中显示BIG5码繁体汉字”指的是在Internet Explorer...随着Unicode编码的普及,现在的网页和软件通常都使用UTF-8编码,但对于访问一些老旧的繁体中文网站,了解如何处理BIG5码仍然很有必要。

    通用简体中文与繁体中文互转完全版

    JavaScript的转换通常基于Unicode编码,因为它是所有现代浏览器都支持的字符编码标准,能兼容简体和繁体中文。 在实际应用中,这两种资源可以单独或结合使用,根据项目需求和服务器环境选择合适的方案。例如,如果...

    念青繁体五笔输入法(繁体中文操作系统下)

    在安装过程中,用户需要注意的是,确保自己的操作系统支持繁体中文,并且兼容该输入法。同时,为了保护计算机安全,应从官方或信誉良好的下载源获取软件,避免下载带有病毒或恶意软件的版本。安装后,用户可以在系统...

    永宏PLC编辑软体winproladder繁体中文版.rar

    永宏PLC编辑软体WinProLadder是一款专为永宏系列可编程逻辑控制器(PLC)设计的编程工具,其繁体中文版为国内广大用户提供了方便的语言环境,使得编程工作更为便捷。该软件是PLC编程人员进行程序编写、调试和维护的...

    VB6.0繁体中文专业版sp6补丁

    安装这个补丁的步骤通常是:首先,确保你已经正确安装了VB6.0繁体中文专业版;其次,运行这个补丁文件,按照提示进行操作,系统会自动检测当前版本并应用更新;最后,重启计算机,让更改生效。 总的来说,"VB6.0...

    繁体中文11111.zip

    这个“语言包”就是为了让Tesseract能够支持繁体中文而设计的。 【压缩包子文件的文件名称列表】中: 1. `chi_tra.traineddata` 文件是Tesseract OCR用于识别繁体中文(Traditional Chinese,简写为tra)的主训练...

    HaiwellHappy PLC编程软件 繁体中文.rar

    软件支持多种通讯协议,如Modbus TCP/IP、EtherNet/IP、Profinet等,能够轻松实现与其他设备或系统的数据交换,构建智能化的自动化系统。 六、适用范围 海为Happy PLC编程软件广泛应用于制造业、能源、交通、楼宇...

    汉字简体繁体参照表(数据库)

    在IT行业中,汉字简体繁体参照表的应用广泛,比如在开发多语言软件时,为了支持简繁体切换,开发者会使用这样的数据来实现文字转换。此外,搜索引擎优化、文本分析、机器学习等领域也可能用到此类数据,进行语言模型...

    WinRAR 64位 繁体中文版 【现在简体中文版不支持去除广告】

    WinRAR 64位 繁体中文版,支持去除广告,官网的软件没有f墙下载很慢,所以发布在这方便大家下载。广告去除方法就是添加“rarreg.key”文件,具体网上搜 很多教程。

    繁体软件乱码消除补丁(解决繁体乱码工具).rar

    “繁体软件乱码消除补丁”是一种专门针对繁体中文乱码问题设计的修复工具,它的主要目的是为了帮助用户在使用繁体中文软件时避免出现文字显示异常的问题。这个补丁可能包含对操作系统内核的修改,更新了字体库,或者...

    Microsoft AppLocale繁体系统用简体软件

    这个工具的主要目的是解决在简体中文系统上运行繁体中文或者其他语言的软件时可能出现的乱码问题。AppLocale通过创建一个临时的区域设置环境,使得程序能够以它原本设计的语言环境来运行,从而避免了字符编码不匹配...

    Crystal Report xtreme 繁体中文版

    在这个繁体中文版中,用户可以享受到更加贴近华人习惯的操作界面和丰富的文档支持。 报告设计是 Crystal Report 的核心,它允许用户从各种数据源(如数据库、Excel表格、文本文件等)提取信息,并以美观、易读的...

    台湾专业繁体全拼软件下载

    在IT行业中,中文输入法是不可或缺的工具,特别是在台湾地区,由于使用的是繁体中文,因此繁体全拼软件在日常工作中扮演了重要的角色。"台湾专业繁体全拼软件下载"这一标题揭示了我们讨论的主题,即一款专为台湾用户...

    乱码翻译神器【支持日语韩语繁体中文】.rar

    标题中的“乱码翻译神器【支持日语韩语繁体中文】.rar”表明这是一个能够处理乱码并提供日语、韩语以及繁体中文翻译的软件工具包。这个压缩包可能包含了一系列与多语言处理相关的组件和资源,用于帮助用户解决在处理...

Global site tag (gtag.js) - Google Analytics