原创 gb码转换Unicode码之转换表文件

2010-12-30 12:16 4009 15 28 分类: 消费电子

<前言>
如 topic 所示, 这是一个很传统的知识点. 当我们的项目, 需要将 gb码转化为 Unicode 码时, 我们进行大量文章检索后, 郁闷发现, 很难找到现成的转换表文件为我们所用. 在发现一份被定义的转化表头文件后, Allen 如获珍宝, 立即将该转换表数组, 做成一个转换文件, 以节省同行进行同议题探讨的时间.

<工作步骤>
1. 获取gb2unicode 头文件:
因为匆忙工作, 未能记录下从哪位同仁的blog中获得, 该 gb2unicode 的码表头文件.对此这里表歉意了. 该头文件定义如下:
//#typedef  unsigned short int   uint16; 
#define MAX_UNI_INDEX  6768

//const uint16 GB_TO_UNI[MAX_UNI_INDEX][2]=
const unsigned short int GB_TO_UNI[MAX_UNI_INDEX][2]=
 {
 
{0x554A,0xB0A1},//GB2312:啊
{0x963F,0xB0A2},//GB2312:阿
{0x57C3,0xB0A3},//GB2312:埃
{0x6328,0xB0A4},//GB2312:挨
// ...
{0x9F3D,0xF7FC},//GB2312:鼽
{0x9F3E,0xF7FD},//GB2312:鼾
{0x9F44,0xF7FE}//GB2312:齄
};


2. 生成 gb2unicode.bin 文件:
void CBuild_GBtoUnicode_fileDlg::OnButtonBuild()
{
 CString strPath = GetDeviceFullPath();
 CString strFileName = strPath + "gb2unicode.bin";

 // build file
 CString sTemp;
 CFile file( strFileName, CFile::modeCreate | CFile::modeWrite );

 BYTE tmp[4];
 memset(tmp, 0, sizeof(tmp));
 for(int i=0; i  tmp[0] = GB_TO_UNI[0]>>8;
  tmp[1] = (BYTE)GB_TO_UNI[0];
  tmp[2] = GB_TO_UNI[1]>>8;
  tmp[3] = (BYTE)GB_TO_UNI[1];
  
  file.Write(tmp, sizeof(tmp));
 }
 file.Close();

 CString sMsg = "Build " + strFileName + " successed!";
 AfxMessageBox(sMsg);

}

3. 使用二分法基于GB码之索引查找Unicode 码 
void CBuild_GBtoUnicode_fileDlg::OnButtonTrax()
{
 BYTE sTemp[4];
 
 memset(sTemp, 0, sizeof(sTemp));
 m_editChar.GetWindowText((char*)sTemp, sizeof((char*)sTemp));

 UINT len = strlen((char*)sTemp);
 UINT index = 0;

 BOOL flag = FALSE;
 if(len == 1) {
  if(sTemp[0] > 127) { flag = TRUE; }
 }
 else if(len == 2) {
  index = (sTemp[0]<<8) + sTemp[1];
  if( (index<0xb0a1) || (index>0xf7fe) ) { flag = TRUE; }
 }
 else {
  flag = TRUE;
 }

 if(flag == TRUE) {
  AfxMessageBox("Please input the correct Chinese char or ascII char!");
  return;
 }

 // do trax
 CString sSource, sDirection;
 // arcII char
 if(len == 1) {
  sSource.Format("0x%x", sTemp[0]);
  m_editSrc.SetWindowText(sSource);

  sDirection.Format("0x00 0x%x", sTemp[0]);
  m_editDrt.SetWindowText(sDirection);

 }


 // gb char with lookup table of bin file
 else if(len == 2) {
  sSource.Format("0x%x 0x%x", sTemp[0], sTemp[1]);
  m_editSrc.SetWindowText(sSource);

  // find unicode code based on gb code
  CFile file;
  CString strPath = GetDeviceFullPath();
  CString sBinFilename = strPath + "gb2unicode.bin";
  if(!file.Open(sBinFilename, CFile::modeRead)) {
   AfxMessageBox("File can NOT be openned!");
   return;
  }

  // half mothed
  int low,high,mid;
  low = 0; high = MAX_UNI_INDEX;
  UINT gbcode_mid = 0;
  BYTE tmp[2];
  while(low  {
   mid = (low+high)/2;
   file.Seek((mid<<2)+2, CFile::begin);
   file.Read((char*)tmp, 2);
   gbcode_mid = (tmp[0]<<8) + tmp[1];

   if( index < gbcode_mid ) high--;
   else if( index > gbcode_mid ) low++;
   else break;
  }
  if(low>high) {
   AfxMessageBox("Cannot find gb char in current gb2unicode table!");
   return;
  }


  // result
  file.Seek( (mid<<2),  CFile::begin );
  file.Read((char*)tmp, 2);
  
  sDirection.Format("0x%x 0x%x", tmp[0], tmp[1]);
  m_editDrt.SetWindowText(sDirection);
  
  file.Close();

 }

}

<验证>
使用一个测试工具, 我们验证了头尾以及中间若干GB码. 其结果与头文件之码表数组均一一匹配.

<总结>
在GB to UNICODE 这个传统的topic 中, 我们借助网络查询, 在接近1个工作日的时间内, 并没有找到一个合适的转换文件.
故基于一个转化数组的帮助下, 我们制作了该转换文件, 一般可用于保存在 FLASH 中, 供同行们使用 MCU 来检索对应的 UNICODE 码. 同时, 要指出因为二分法的使用, 查表的速度应符合普通应用.
我们记录工作于此 blog, 我们希望能有助于同行进行类似的工作,  不再浪费宝贵的工程时间于此传统议题上.


Allen 作于深圳福田
2010.12.30

PARTNER CONTENT

文章评论13条评论)

登录后参与讨论

用户1085119 2011-8-8 09:07

不错 好东东

用户1322273 2011-1-5 21:51

用户1291225 2011-1-5 08:42

谢谢博主分享,下载学习

用户1371612 2011-1-4 09:42

不错

用户1101468 2011-1-3 22:24

谢谢,已下载学习

allen_zhan_752827529 2011-1-3 11:49

回 JingtongACT : 我的目的是, 提供了 27k bytes 左右大小的按序排列 GB 码与Unicode 的转换表文件. 你的工具很不错! 就是太豪华了, 是否也完成该文件提供查表? 这个是我的topic 的关注点. 回 BadCat : 在一个常见的 arm7 下, 资源往往比较有限, 常见的小型系统中, 甚至连uCosII都不跑的``` 遑论 windows, linux```

用户1190859 2011-1-3 11:36

不需要这样, 可以直接使用libiconv就好了,支持中文(GB18030, BIG5...)、日文、德文....到Unicode的转换;我的程序在处理多国语言支持时都是用这个; libiconv支持跨平台:Windows、Linux上都可以使用(我们曾在Windows上和MIPS的Linux上用过)

用户1409907 2011-1-3 11:21

试试这个工具, 就不用那么麻烦了, 要多少就有多少的。 http://forum.eet-cn.com/BLOG_ARTICLE_6275.HTM

用户1379464 2011-1-3 09:14

good material and wish God bless you.

f737_486061703 2010-12-31 09:09

谢谢,已下载学习。
相关推荐阅读
allen_zhan 2023-02-27 19:08
对"三极管"译名由来的探讨
想讨论一个有意思的话题:今天中国大陆的电子业界, 为何将 BJT 称呼为 "三极管"? 或因其象形, 前辈自行进行随意的不严谨定义么? 带着疑问我们做了一下延伸查阅, 或得出这样的结论, 即中译名"三...
allen_zhan 2023-02-19 18:15
对知乎提问"为何三极管的一个PN结工作在反偏"的回复
将这个回复, 也发表在博文中, 作为自己的一个学习笔记叭.知乎问题: "三极管里面的PN结相当于二极管,为什么里面PN结加反向电压也能导通?"我的回复:首先, 二极管的"反向"概念, 容易给初学者某种...
allen_zhan 2023-02-18 10:17
从肖特基二极管到PN结与三极管
最近数个工作日的兴趣是回顾电子基础器件的发明/发展历史, 期待夯实技术基础的底蕴. 在学习与搜索资料的过程中, 顺便对知乎的一个同学的基础问题, 进行了回复. 不小心回复一下就成了千字文, 觉得挺有趣...
allen_zhan 2023-01-28 11:53
微功率 ISM 频率探讨相关文档组总结
不知不觉, 自开启关于微功率频率的话题起, 即从第一份文章写就到今天总结之日, 已经接近 10 个工作日左右. 早先的想法是对工程界未来的微功率设备相关项目, 从项目规划开始, 对选择系统, 频率, ...
allen_zhan 2023-01-27 22:50
关于 LoRa 应用场景的讨论
说明: 本文中斜体部分表示来自公告文件的部分内容剪贴或合并整理.1. "第52号文" 对 470MHz 的约束引自 如下:(四)民用计量仪表限在建筑楼宇、住宅小区及村庄等小范围内组网应用,任意时刻限...
allen_zhan 2023-01-25 13:24
ISM 频段中 2.4G 与 5.8GHz 设备的使用与限制
说明: 本文中斜体部分表示来自公告文件的部分内容剪贴或合并整理.1. ISM 频段定义中的 2.4G 与 5.8GHz正如同 文中确定的, 2.4G, 5.8GHz 属于中国大陆 ISM 频段的定义...
EE直播间
更多
我要评论
13
15
关闭 站长推荐上一条 /3 下一条