@ZEAL Blog·厉
We stand alone,
TOGETHER.

繁简体(GB<=>Big5)字符串转化的JAVA方式实现

Posted by zeal on 2005-04-28 10:32 , 12901 characters |  + 2 - 1   English
转载请保留本行原始出处声明信息 : http://www.zeali.net/entry/19 MaDe1nZEAL
本文提供一个java实现中文字符繁简体互换的zip包以及主要的源代码实现说明。

繁简体(GB<=>Big5)中文字符的转化实现原理很简单,就是根据两种码表的编码规则,创建两者之间的字符对应关系表,通过程序读取这个映射表来自动查出另一种编码方式下对应字符的字节编码,从而进行逐字节的内容替换。 

主功能实现的GB2Big5.java源代码如下:

##############################
直接调用GB2Big5只适用于对于少量字符的转化,当需要对整个jsp页面根据用户需要进行编码转化
的时候,就需要使用到taglib的功能。
具体配置使用步骤如下:

1.在WEB-INF/目录下增加GB2Big5Wrapper.tld文件,内容如下:

2.在需要进行转化的JSP页面里面加上:
<%@ taglib uri="/WEB-INF/GB2Big5Wrapper.tld" prefix="zealLi"%>
<zealLi:GB2Big5Wrapper isbig5="true">
任何你需要转化的东西
</zealLi:GB2Big5Wrapper>

比如test.jsp源代码如下 =>

附件 GB2Big5.zip(108,182 bytes): 发布形式的类库zip文件,可直接使用 发布形式的类库zip文件,可直接使用

附件 GB2Big5_Project.zip(38,685 bytes): JBuilder工程文件,提供完整的源代码 JBuilder工程文件,提供完整的源代码

相关日志: PHP下中文编码各种格式间的转换类 , 中文字符编码格式判断

Last Modified on 2007-05-24 16:30
66 条评论:
- xiaomin () 于 2005-04-29 19:14
我在Windows下面结果很好。 可是在Linux下面转换的结果不对, 是不是要重新生成两个table文件?
- zeal2005-04-29 19:26
你需要给linux设置环境变量
LANG=zh_CN.GBK
或者在linux带参数重新编译。
- chenxg () 于 2005-07-14 16:20
请教:gb->big5转换出来的并非big5码,而是gbk繁体,请问原因?
- zeal (link) 于 2005-07-14 22:56
不会吧?你具体是怎么操作的?
- aman () (link) 于 2005-08-04 11:51
,能不能套用在php
- zeal (link) 于 2005-08-04 11:53
php版本的繁简体转化请参阅这片帖子:
http://www.zeali.net/blog/entry.php?id=5..
- pengwenming () 于 2006-03-12 13:51
将简体转为繁体没什么问题,但将繁体转为简体就会出现乱码-我的系统是简体。
解决方法是将gb2big5.java中的big52gb(String inStr)函数中的
byte[] Text = new String(inStr.getBytes(),"BIG5").getBytes("BIG5");代码行改为
byte[] Text = inStr.getBytes("BIG5");

感谢zeal的无私奉献,如果有时间的话,可否麻烦你告诉我那两个码表从何处可以获得
预先表示感谢!!!另外,很好奇你是否身居港台?多嘴了
- zeal (link) 于 2006-03-12 16:17
码表在本文最后提供的两个下载压缩包里面都有。你解开即可。
p.s. 我是上海嘀。
- pengwenming () 于 2006-03-13 19:37
没想到你回复这么快,谢谢!可能是我没说清楚,我的意思是你是从何处获得那两个码表的。
另外,你的StreamConverter类是为“从网络连接获得输入流然后转为字节数组”而写的吗?
因为我发现你特地对流堵塞情况进行了处理,不知道为何如此。
不过有一点疑问,input.available() != 0即使成立,
status = input.read(buffer)执行时在具备以下条件后也可能出现堵塞情况:
1,没有达到文件末尾
2,没足够的有效数据填满buffer
我是这样解决的,希望进一步交流
byte[] buffer=new byte[in.available()];
ByteArrayOutputStream bos=new ByteArrayOutputStream();
int byteNum=in.read(buffer);
while(byteNum!=-1){
bos.write(buffer,0,byteNum);
byteNum=in.read(buffer);
}
in.close();
byte[] sContent = bos.toByteArray();
bos.close();
最后,我也在上海,地球很小啊!
- zeal (link) 于 2006-03-16 23:28
原来如此。这两个码表的原始出处已经无从考证了,是从Google上搜来的。
这个StreamConverter你猜得没错,最初确实是设计来读取URL的内容而写,属于我为公司开发架构编写的common library里面的一个util类。对于GB2Big5来说,其实只是用它来完成把输入字符流转化成字节数组。第一版的GB2Big5采用的是java.io.RandomAccessFile来完成文件读取,后来觉得要打jar包,把码表文件作为资源一起打进去,用io来读取并不通用,所以改成使用这个StreamConverter来转化通过getResourceAsStream得到的输入字符流。
由于历史原因,对于流堵塞进行的特殊处理是为了使用于多线程环境的网络数据读取。对于GB2Big5来说,你所提供的写法完全可以。
- pengwenming1 () 于 2006-03-18 21:02
谢谢你的回复!这两天利用空闲时间认真地了解了一下字符集编码的问题,把原来那些纷乱的思路理了一下,
你的源代码让我明白了很多东西,谢谢你!
关于繁体转简体的问题,你的代码用于big5,我提供的代码行用于以GBK为内码的繁体。
以后可能还有很多问题要求助你,希望不吝赐教!
- pengwenming1 () 于 2006-03-19 14:53
搞错了,关于繁体转简体的问题,应该反过来才对。
- shixingdong () 于 2006-04-05 17:00
gb->big5转换出来的并非big5码,在浏览器中是gbk繁体,而不是繁体BIG5

有没有什么解决方法?
- shixingdong () 于 2006-04-07 12:02
搞了很好,只有将gb码转成Unicode即在BIG5页面中处理转码问题。
- eq1688 () 于 2006-07-09 17:43
你好, shixingdong

gb->big5转换出来的并非big5码,在浏览器中是gbk繁体,而不是繁体BIG5

搞了很好,只有将gb码转成Unicode即在BIG5页面中处理转码问题。”

是怎么在BIG5页面中处理转码问题的才能转成繁体BIG5
- 梦人 () 于 2006-10-09 00:15
你好,zeal。我想用这个做一个判断,在中文简体繁体互相转换的时候,如果在转换为简体(或繁体)过程中,本来就是简体(或繁体)就不转换,这怎么处理? 谢谢!
- 梦人2006-10-09 15:58
谢谢
- zeal (link) 于 2006-10-09 15:54
to 梦人:一般来说要对字符编码格式进行判断就是根据各种编码两个字节的起止范围作判断,如果符合起止范围就认为是某种字符编码。但理论上来说不同的字符编码有可能会采用同样的字节范围,所以这种方法并不是完全准确的。只有采用unicode大字符集才能够唯一确定某个字符是什么文字。
附上 PHP 4 source 里面对于中文几种常用字符集的范围宏定义,你可以根据这个范围来实现自己的字符编码格式判断方法。

/* Support for Chinese(BIG5) characters */
#define isbig5head(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xf9)
#define isbig5tail(c) ((0x40<=(uchar)(c) && (uchar)(c)<=0x7e) || (0xa1<=(uchar)(c) && (uchar)(c)<=0xfe))

/* Support for Chinese(GB2312) characters */
#define isgb2312head(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xf7)
#define isgb2312tail(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xfe)

/* Support for Chinese(GBK) characters */
#define isgbkhead(c) (0x81<=(uchar)(c) && (uchar)(c)<=0xfe)
#define isgbktail(c) ((0x40<=(uchar)(c) && (uchar)(c)<=0x7e) || (0x80<=(uchar)(c) && (uchar)(c)<=0xfe))
- sailbefore () 于 2006-10-10 17:41
zeal 您好,谢谢您给我们提供了这么好的文章,上面那个PHP的判断能帮用Java写一下吗,谢谢!
- zeal (link) 于 2006-10-12 00:57
中文字符编码格式判断: http://www.zeali.net/entry/444 , check it out.
- sailbefore2006-10-23 11:13
Zeal老兄,自从我用您写的MyTest这个类把简体字转成繁体字后觉得很过瘾,所以想把繁体字转成简体字可以打入-gb参数后出现的是一堆问号,这是为什么啊,我记得刚下载下来的时候我好像成功转过一次...
- sailbefore2006-10-23 11:23
这是我测反回的结果
String [中國] converted into:
[ ??]
- zeal (link) 于 2006-10-23 15:05
因为这个转换只是gb和big5编码之间的转换。你输入的中國两个字其实应该算是gbk编码而不是big5。你需要传入big5编码的繁体字才会被正确转换。
- simba () (link) 于 2006-11-06 16:55
我的系統是基於utf8編碼的,數據庫中的也是utf8格式數據,用這個程序好像找不到對應字,請問如何解決?
多謝zeal !
- zeal (link) 于 2006-11-06 17:00
请参考本篇日志最后提供的关于" PHP下中文编码各种格式间的转换类"的链接.在那篇日志里面有处理utf8格式字符的转换代码,当然是用php来实现的,你可以根据提供的码表去实现对应的java版本。
- alex2006-12-15 14:20
有一个字 (後)转不过来,请问怎么解决?(谢谢你提供的代码)
- zeal (link) 于 2006-12-15 14:56
因为字符对应码表都是手工进行对应的,如果发现有的字符转码不正确或找不到的话,可以使用类里面提供的两个方法 resetBig5Char / resetGbChar 来把正确的对应关系重新写入码表。
- tinen () 于 2007-01-16 14:06
谢谢zeal。请问,但是GB->BIG5似乎不对?BIG5在简体系统中应该显示乱码,中国两个字转换为big5不应该是い瓣吗?而您的程序转换出的是中國。这两字在繁体系统中仍旧是乱码呀!?
PS:不好意思,本人脑袋不太好使,经常会转不过弯,希望您提点下!谢谢=v=
- zeal (link) 于 2007-01-16 16:06
这是测试代码为了显示出来便于观察,在显示的时候又通过java getBytes 把 big5 的字符串转化成 统一的 java unicode 之后再显示了出来。你在实际使用的时候直接把字节数组写入文件或输出,不要再进行转化就可以了。
- tinen () 于 2007-01-16 22:19
原来如此!!非常感谢您的详解=v=。受教了。
- snowtank () (link) 于 2007-01-18 09:24
Zeal我刚刚测试了一下,gb2big5是可以的,但是big52gb确转换不正确
代码如下
String str5 = new String(GB2Big5.getInstance().big52gb("天天互動"),"GBK");
System.out.println(str5);
请赐教,谢谢
- zeal (link) 于 2007-01-18 09:40
和上面 tinen 说的是同一个问题,“天天互動”其实已经不是 big5 的字符而是 unicode 的了。你在使用big52gb的时候需要提供的是类似 い瓣 这样看不懂的 big5 码字符。
- snowtank () 于 2007-01-18 16:56
谢谢,我是想把天天互動转换为天天互动,是哪里有错误呢?
- zeal (link) 于 2007-01-18 17:40
天天互动 对应的big5码是 ぱぱが笆 ,而不是 天天互動 ,这样说不知道你是否能够理解了。你可以使用我在本文末尾提到的 中文字符编码格式判断 ( http://www.zeali.net/entry/444 ) 一文了解更多关于字符编码的问题。如果你需要的是 GBK 中的繁体转换到 GBK/GB2312 简体的话,需要相应的码表来完成字符对应的工作。
- tinen () 于 2007-01-19 11:12
zeal,请问如果要把简体的unicode同繁体的unicode互相转换该怎么做呢?
- tinen () 于 2007-01-22 17:49
zeal,你好,我在繁体的系统中尝试运行你的程序,但是输出全都是?号,这是什么原因?两个table的问题吗?
- smoke2007-07-20 11:23
zeal老大,我用你的方法能把big5=>gbk,但我想不管用户输入繁体big5或简体gbk,都能自动转为简体gbk,或者能自动识别用户输入繁体或简体。怎么办?
- zeal (link) verified2007-07-20 11:59
请参见楼上的一些回复。
- smoke2007-07-20 12:45
zeal老大,我利用你的转码方法,做了个函数,可以识别用户输入是繁体或简体。终于搞定这个麻烦的东东!谢谢你!
- zzz2007-08-09 14:16
雜誌的“誌”转换后乱码
- yakie2007-10-19 10:46
楼主的代码我试过了,有两个地方有问题,需要改一下
1,用到GBK的地方,我需要改成GB2312才能工作。
2,所有str.getBytes()方法,都没有传参数进去,这样会导致默认用系统的encoding,如此以来,如public byte[] gb2big5(String inStr)这个方法,如果在繁体系统下,会导致错误的转换,解决办法是,在此方法里面用str.getBytes("GB2312")来代替。其他str.getBytes()的方法也要指定相应的encoding,这样才能做到平台无关。
- yakie2007-10-19 10:48
tinen (email) 于 2007-01-22 17:49
zeal,你好,我在繁体的系统中尝试运行你的程序,但是输出全都是?号,这是什么原因?两个table的问题吗?

我的这个方法可以解决你的问题
- oldyoungj2007-11-29 17:45
GBK内简繁互转是怎么解决的?麻烦告知
- squall2008-01-16 14:07
雜誌的“誌” 和 檬面的"檬"字 转不了

试过用resetGbChar()和resetBig5Char()方法好像没有效果
- squall2008-01-18 15:41
原来是可以用resetGbChar()和resetBig5Char()来更新码表的

之前是用误用了,所以结果好像没有效

PS:如果想这个程序在繁体操作系统时生效的话最好指定一下编码

PS:帮到大忙了,太感谢zeal
- squall2008-01-18 16:17
好像是错觉,有调用reset方法时才有效,还以为它已经写入文件了

(看过文件的日期与当前日期是一致的啊,理论上有进行过写入操作)

,没有调用时还是没效,难道每次都要调用一下reset方法来更新字符??
- zeal (link) verified2008-01-18 17:11
如果你用的是zip包的话,需要自己把包解开之后运行reset写入码表之后在把新生成的table文件打包回去。
- http://openid.zeali.net/u/heiheben (link) verified2008-09-18 11:11
有没有gbk中简繁转换的方法
- http://openid.zeali.net/u/heiheben (link) verified2008-09-18 11:12
zeal 您好
- http://openid.zeali.net/u/heiheben (link) verified2008-09-18 11:13
看了一些这方面的文章 觉得还是一知半解
- relyang2008-12-05 14:57
zeal (link) verified 于 2008-01-18 17:11
如果你用的是zip包的话,需要自己把包解开之后运行reset写入码表之后在把新生成的table文件打包回去。

zip里面没有r发现eset,不知道是怎么回事?还有就是想请教一下,如果utf8与Big5简繁相互转换,该如何处理?谢谢
- http://openid.zeali.net/u/relyang (link) verified2008-12-10 10:22
你好,zeal !请问如何更新你说的gb,big5的码表文件?
- zeal (link) verified2008-12-10 14:10
to relyang:
请参阅之前其他人的回复。在类里面有resetGbChar和resetBig5Char两个方法。
- http://openid.zeali.net/u/relyang (link) verified2008-12-15 09:53
zeal,我现在需要把转换过来的简体繁体全部(不管是输出Big5还是GB)转换成utf8输出该如何处理?谢谢你的回复。
- zeal (link) verified2008-12-15 10:14
java内部都是采用unicode的,如果只是需要进行字符集的转换,只需要
new String(oldStr.getBytes(),"UTF-8").getBytes("UTF-8");
就得到了utf-8编码的字节流。
- http://openid.zeali.net/u/relyang (link) verified2008-12-15 11:44
我把这里 new String(inStr.getBytes(), "gb2312").getBytes("gb2312") 改写成这样:
new String(inStr.getBytes(), "UTF-8").getBytes("UTF-8"),
得到的是如:
[这里] ---->[錕斤拷錕斤]
这是什么原因呢?,我的操作过程是这样的:
读取文本文件,然后转换成简体或者繁体字。
- http://openid.zeali.net/u/relyang (link) verified2008-12-16 11:33
zeal,我想这样处理能行吗?我不管前面是如何处理简体跟繁体转换的,就是在输出的时候用CharsetEncoder,CharsetDecoder进行UTF8输出,这样是不是可以解决utf输出的问题呢?
- relyang () 于 2008-12-22 09:56
- tinen (email) 于 2007-01-16 14:06
谢谢zeal。请问,但是GB->BIG5似乎不对?BIG5在简体系统中应该显示乱码,中国两个字转换为big5不应该是い瓣吗?而您的程序转换出的是中國。这两字在繁体系统中仍旧是乱码呀!?
PS:不好意思,本人脑袋不太好使,经常会转不过弯,希望您提点下!谢谢=v=
- zeal (link) 于 2007-01-16 16:06
这是测试代码为了显示出来便于观察,在显示的时候又通过java getBytes 把 big5 的字符串转化成 统一的 java unicode 之后再显示了出来。你在实际使用的时候直接把字节数组写入文件或输出,不要再进行转化就可以了。
--------------------------------------------------------
请教zeal,这里该如何处理,我现在遇到和这个一样的问题,谢谢你的指教!比较急。
- relyang2008-12-22 10:36
zeal,你说“你在实际使用的时候直接把字节数组写入文件或输出,不要再进行转化就可以了。”,需要如何处理呢??比如像:
"拉"
"べ"
"じ稨"
"じ繟バ"
"瑌"
"拉瓁"
"べ屡"
"じ狶"
"瓾狶"
"じ秏"
在繁体系统里面都能显示繁体字,而我现在要处理的就是要把像这样的编码转换陈简体中文,该怎么处理呢?我参见了上面的恢复,还不清楚如何处理,希望你能指点一下,非常谢谢!
- http://openid.zeali.net/u/relyang (link) verified2008-12-23 11:57
zeal,更新码表时抛异常:
java.io.FileNotFoundException: orgrelyangutilgb-big5.table (系统找不到指定的路径。)
请问为何打不开码表文件??请问这是什么问题啊?
- yt213yt2008-12-30 16:13
你好,zeal!我想把那两个码表文件变大行吗?不知道如何处理。我现在用你的方法来更新字体如:恏<----->邨 昪<--->脷。提示:java.lang.ArrayIndexOutOfBoundsException: 1
出现异常。我用来更新好多香港字都出现这个问题,是怎么回事啊??谢谢!
- feng_sundy () (link) 于 2009-01-09 11:13
url = "http://www.baidu.com/s?wd=%D6%D0%87%F8%D..

一个referer来源里面有以上的链接,可以取得关键字,可是无法将关键字转换为对应的编码,虽然百度是gb2312编码,可是如果输入繁体的字符搜索,这个时候用UrlDecode.decode(wd,"gb2312")解码出来的字符就是乱码。
这个里面的wd搜索关键字,有可能是繁体的,有可能是简体,还有可能是其他的字符,如何取得wd的对应编码呢?
- zeal (link) verified2009-01-09 11:37
试试用gbk代替gb2312.
- feng_sundy () (link) 于 2009-01-09 11:48
gbk代替gb2312.是可以。
但是我要求的可能还有google.com,yahoo。tw等其他搜索引擎也支持,google就是utf-8,能否有一个程序来的判断是什么编码呢?
就像流量统计,是怎么解决各种关键字不显示成乱码呢
- phoenix () 于 2009-02-12 21:48
感谢你提供的简繁转化代码,通过你的代码,加上tlkeditR13b(http://nwvault.ign.com/View.php?view=oth..),我成功的将"绝冬城之夜2白金合集"中(dialog.TLK)的繁体转化成简体。再次感谢!

但是,由于tlkeditR13b采用的是GPL协议,我必须公开tlkeditR13b修改后的代码,我的想法是直接将修改后的版本寄回tlkeditR13b的作者,由他(她)本人决定是否接受代码。

但是,同时寄回的还有你的简繁转化代码以及通过Eclipse生成的Jar文件,而简繁转化代码没有附带版权说明,所以请问,您是否允许我这样做?谢谢!
- zeal (link) verified2009-02-12 21:54
您只需要保留原始的注释信息即可。Thx.
Since 2005.04.27  梦想 就像鸡蛋 要么孵化 要么臭掉RSS Feed (Entries) | Back To Home | @ZEAL | 沪ICP备05024379号