Chinaunix

标题: 请教。关于汉字编码转换UTF-8->GB2312。 [打印本页]

作者: sanor    时间: 2008-06-11 13:27
标题: 请教。关于汉字编码转换UTF-8->GB2312。
大家有做过这个的实现吗?UTF-8到GB2312的转换。
linux汉字编码为UTF-8,汉字库编码为GB2312。所以需要UTF-8到GB2312的转换。
交叉工具链中没有iconv函数,所以需要自己实现。网上搜到的全都是windows下的不可移植代码。
或者unicode到GB2312的转换。现在可以从UTF-8转到unicode。
多谢大家不吝赐教。
作者: net_robber    时间: 2008-06-11 13:28
man iconv
作者: ruoyisiyu    时间: 2008-06-11 13:30
原帖由 net_robber 于 2008-6-11 13:28 发表
man iconv

汗~~人家说了没有iconv了
作者: jigloo    时间: 2008-06-11 13:31
关键字:gb2312.txt
网上很多人作过这个
http://download.csdn.net/source/205564
作者: cugb_cat    时间: 2008-06-11 13:31
把iconv的代码下载下来,抄一抄~~!
作者: jigloo    时间: 2008-06-11 13:33
iconv的代码比较复杂,不适合楼主的需要。(估计楼主是要在嵌入式上用)
作者: net_robber    时间: 2008-06-11 13:41
如5楼说的,摘出需要的部分用

源代码都给你了,自己复制一下不好么??
作者: sanor    时间: 2008-06-11 13:55
汗。iconv源码。。
作者: cobras    时间: 2008-06-11 14:07
UTF只是UNICODE的一种表现形式,
UTF-8是用字节序列来表示UNICODE
还有UTF-16和UTF-32等等形式
若要将UTF-8转换为GB2312,应该先将UTF-8转换为UNICODE(一般用UTF-16表示即可,当然用UTF-32表示就更完整了),然后通过查表来实现UNICODE到GB2312的转换.
作者: sanor    时间: 2008-06-11 15:54
多谢楼上指点。那请再问我如何通过查表得到unicode与gb2312间的映射关系?是否有公式或法则?
刚才看了unicode字符映射表,目前状况大致如:
汉字“啊”,通过utf-8转unicode得到其字符编码为0x554a,unicode字符映射表里0x554a的位置确实是“啊”字。但是不知道如何将之与gb2312的1601对应。“啊”在gb2312汉字库中的区位码是1601。
请指教。谢谢。
作者: cobras    时间: 2008-06-11 16:49
这个简单,写个Win32程序在Windows xp中运行
作者: safedead    时间: 2008-06-11 16:50
标题: 回复 #1 sanor 的帖子
cp /usr/share/i18n/charmaps/GB18030.gz ./
gzip -d GB18030.gz
得到文本文件GB18030
里面就是unicode和GB18030的对应关系
其它的依此类推

这个文件很容易看懂,编个程序读取后就得到转换表
利用unicode为桥梁,可以进行各种字符集转换
作者: figofuture    时间: 2008-06-11 21:05
iconv也没有什么复杂的,基本原理不正如楼上说言吗?!
作者: jigloo    时间: 2008-06-11 21:16
最烦楼上这样的,没看过代码就乱说。
作者: nicozhou    时间: 2008-06-11 21:45
等我找找,前两天我还在折腾这个。
作者: nicozhou    时间: 2008-06-11 21:47
应该差不多的吧,不知道够不够lz用。我们是先自己建好unicode2gb2312的映射表,然后查这张表(二分法)的。其它的只要调这个接口就可以了。

UTF8应该可以类似这样做吧。反正我这边似可以正常的显示中文的。

UINT16 Unicode_to_Gb2312(UINT16 unidata)
{
    UINT16                      first = 0;
    UINT16                      last = MAX_UNI2GB_LIST - 1;
    UINT16                      middle = 0;
    UINT16                      des_pos = MAX_UNI2GB_LIST + MAX_UNI2GB_LIST;
    UINT16                      gb_code;

    if(unidata < IG_FONT_ASCII_BEGIN)
    {
        return OSD_FAILURE;
    }
    else if(unidata <= IG_FONT_ASCII_END)
    {
        return unidata;
    }
    else if(unidata < 0x00A4 || unidata > 0xFFE5)
    {
        return OSD_FAILURE;
    }

    while(first <= last)
    {
        middle = (first + last) & 0xfffe;
        if(unicode2gb2312[middle] == unidata)
        {
            des_pos = middle;
            break;
        }
        else if(unicode2gb2312[middle] > unidata)
        {
            last = (middle>>1) - 1;
        }
        else if(unicode2gb2312[middle] < unidata)
        {
            first = (middle>>1) + 1;
        }
    }

    if(des_pos > (MAX_UNI2GB_LIST + MAX_UNI2GB_LIST) - 1)
    {
        return OSD_FAILURE;
    }
    else
    {
        des_pos ++;
        gb_code = unicode2gb2312[des_pos];
        return gb_code;
    }
}

[ 本帖最后由 nicozhou 于 2008-6-11 21:51 编辑 ]
作者: nicozhou    时间: 2008-06-11 21:54
难道额理解错了?
作者: wsswan    时间: 2008-06-11 23:04
上 Google 搜索 gb2312.txt 就能找到对照表,根据里面的算法做就可以了。没啥技术含量。问题是你确定用的是 GB2312 字符集么?要知道 GB2312 连一些基本的标点符号都没有,例如 ·×
作者: figofuture    时间: 2008-06-11 23:31
原帖由 jigloo 于 2008-6-11 21:16 发表
最烦楼上这样的,没看过代码就乱说。

看没看代码很重要吗?有了思路后面不就一个实现而已。去看iconv的源码只不过花费一些时间而已,未必不适合嵌入式系统,你也没有调查过捏。

不过我并不烦你,有容乃大,哈哈!
作者: jigloo    时间: 2008-06-12 09:48
真像你说的这样,那些自己做转换的人都成了傻子?还有容乃大,先看代码再来说话。
作者: redor    时间: 2008-06-12 09:49
原帖由 sanor 于 2008-6-11 13:27 发表
大家有做过这个的实现吗?UTF-8到GB2312的转换。
linux汉字编码为UTF-8,汉字库编码为GB2312。所以需要UTF-8到GB2312的转换。
交叉工具链中没有iconv函数,所以需要自己实现。网上搜到的全都是windows下的不可 ...



一般的转换都是先知道字符集然后转成UNICODE再转成别的字符集....
这个说的是相同的字,如果简体和繁体转就不是这么转了,就需要一个另外的映射表....
作者: safedead    时间: 2008-06-12 10:19
研究过windows的字符集转换工具就知道
unicode是字符集转换的重要桥梁
很关键的,如果某个同型汉字在CJK中都存在,那么对应的unicode是一个
(题外话:韩国曾经干过烂事,搞过不兼容的事情)

unicode针对的是形状,每个unicode对应一个字符图形
在/usr/share/i18n/charmaps里面的是219个字符集对unicode转换表

话说win2000的nls文件比redhat7.2的i18n文件少很多字符集,而且缺字严重
我现在用RHEL5,windows2000之后的系统没有用过
最新的字符映射表可以去www.unicode.org下载

LINUX方面,利用i18n的项目提供的现成字符映射表可以省掉很多麻烦
下面是i18n中GB2312的一段文本,这个文本还看不懂的,就不要搞字符集转换程序了

<code_set_name> GB2312
<mb_cur_max> 2
<mb_cur_min> 1
<comment_char> %
<escape_char> /
% Chinese charmap for EUC-CN = GB2312 = union of ASCII and GB_2312-80
% version: 1.0
% Contact: ha_shao
% Email: hashao@china.com
% Distribution and use is free, even for comercial purpose.
%
CHARMAP
<U0000>     /x00         NULL (NUL)
<U0001>     /x01         START OF HEADING (SOH)
<U0002>     /x02         START OF TEXT (STX)
<U0003>     /x03         END OF TEXT (ETX)
<U0004>     /x04         END OF TRANSMISSION (EOT)
<U0005>     /x05         ENQUIRY (ENQ)
<U0006>     /x06         ACKNOWLEDGE (ACK)
<U0007>     /x07         BELL (BEL)
<U0008>     /x08         BACKSPACE (BS)
<U0009>     /x09         CHARACTER TABULATION (HT)
<U000A>     /x0a         LINE FEED (LF)
...
<U8584>     /xb1/xa1     <CJK>
<U96F9>     /xb1/xa2     <CJK>
<U4FDD>     /xb1/xa3     <CJK>
<U5821>     /xb1/xa4     <CJK>
<U9971>     /xb1/xa5     <CJK>
<U5B9D>     /xb1/xa6     <CJK>
<U62B1>     /xb1/xa7     <CJK>
<U62A5>     /xb1/xa8     <CJK>
...
注意CHARMAP开始,就是映射关系,
三个字段分别表示:unicode编码, C语言char数组元素,注释
排列顺序是按照GB2312
作者: sanor    时间: 2008-06-13 09:36
多谢大家热心相助。这个问题已经解决了。
期间我从unicode到gbk的映射表中摘出了gb2312的那部分做成另一个映射表。然后查表得到。
再次谢谢大家。
至于iconv源码,先让他闪边。。
作者: wifi    时间: 2008-06-30 17:03
好,顶一下。
作者: 思一克    时间: 2008-06-30 17:22
为什么不用函数iconv?
作者: COCOAKE    时间: 2008-06-30 23:27
学这个东西好学吗,编程我是个外行,刚开始介入,代价多多指教,现在我去找个人,去学习,领入门以后自己研究,这样可以吗,认识更多的朋友 ,加QQ:375331406
作者: sunlan    时间: 2008-07-01 09:59
libiconv在windows下是能用的,我一直在用
作者: pilgrim_kevin    时间: 2008-07-08 10:13
又学到了一些。收藏。
作者: benjiam    时间: 2008-07-08 10:33
只问一句 iconv 开发到 1.13  要是都象你们说的这么简单, 那些开发人员是不是弱智啊?
作者: 77h2_eleven    时间: 2008-07-08 13:01
原帖由 cugb_cat 于 2008-6-11 13:31 发表
把iconv的代码下载下来,抄一抄~~!

这种函数都是调用来调用去的。
如果LZ能耐心把iconv代码看透,估计连红尘也能看透了。
作者: keensword007    时间: 2008-07-08 19:28
原帖由 sanor 于 2008-6-11 13:27 发表
大家有做过这个的实现吗?UTF-8到GB2312的转换。
linux汉字编码为UTF-8,汉字库编码为GB2312。所以需要UTF-8到GB2312的转换。
交叉工具链中没有iconv函数,所以需要自己实现。网上搜到的全都是windows下的不可 ...


可以从网上下在iconv的源代码,自行编译,我就自己编译过ARM, MIPS版本的.
作者: blackuhlan    时间: 2008-07-08 19:58
如果楼主需要自己翻译,那么你需要一个翻译表,如果需要别人帮你翻译,那么你需要一个程序。另外iconv是系统自带的,你可能只是没有支持文件(实际上就是翻译表)
作者: aeou    时间: 2008-07-17 07:40
路过,学习一下,呵呵
作者: zlrll    时间: 2008-07-17 10:01
也可以交叉编译个iconv,我就干过这事




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2