搜索
bottom↓
回复: 17

UNICODE 转GB2312 纯C语言 映射法

[复制链接]

出0入0汤圆

发表于 2014-11-17 10:47:21 | 显示全部楼层 |阅读模式
RT:
刚好有需求,UFT8的优势在于多国语言默认兼容,用unicode + uft8的方式做数据传输天生不用考虑多国语言问题,这也是一大优势。
不过UFT8传输汉字需要3个byte。大家看着办咯,

最近是刚需,上位机那边就是用的utf8,所以只能在固件内做unicode转gb2312,因为点阵字库是区位码索引的。

  1. //使用到的文件有unicode转gb2312的映射表 默认是从gb2312转unicode  所以注释掉的部分是把表反序。
  2. //不要吐槽我的渣渣排序算法,赶时间的 而且是WIN 慢点就慢点


  3. #include <stdint.h>
  4. #include <stdbool.h>
  5. //#include <windows.h>


  6. #define MAX_UNI_INDEX  6768

  7. //uint16_t const table_gb2312_to_unicode[MAX_UNI_INDEX][2];
  8. //uint16_t const *const p_table_gb2312_to_unicode = &table_gb2312_to_unicode[0][0];

  9. //uint16_t table_sorted_unicode[MAX_UNI_INDEX];
  10. //uint16_t table_sorted_gb2312[MAX_UNI_INDEX];
  11. //uint16_t table_sorted_section_table[MAX_UNI_INDEX];

  12. #if 0
  13. uint16_t const sorted_unicode[MAX_UNI_INDEX];
  14. uint16_t const sorted_gb2312[MAX_UNI_INDEX];

  15. const uint32_t c_un_sorted_value = 0xFFFFFFFF;
  16. uint32_t sort_result[MAX_UNI_INDEX];

  17. void init_sort_result_buffer(void)
  18. {
  19.     for (int i = 0; i < MAX_UNI_INDEX; i++){
  20.         sort_result[i] = c_un_sorted_value;
  21.     }
  22. }

  23. void sort_form_zero_to_end(void)
  24. {
  25.     uint16_t current_min_index = 0;
  26.     uint16_t min_tmp = c_un_sorted_value;
  27.     for (int i = 0; i < MAX_UNI_INDEX; i++){
  28.         for (int j = 0; j < MAX_UNI_INDEX; j++){
  29.             if (sort_result[j] == c_un_sorted_value){
  30. //                uint16_t tmp = p_table_gb2312_to_unicode[2*j+1];    //sort by gb2312
  31.                 uint16_t tmp = p_table_gb2312_to_unicode[2*j];        //sort by unicode
  32.                 if (tmp < min_tmp){
  33.                     current_min_index = j;
  34.                     min_tmp = tmp;
  35.                 }
  36.             }
  37.         }
  38.         sort_result[current_min_index] = i;
  39.         min_tmp = c_un_sorted_value;
  40.         current_min_index = 0;
  41.     }
  42. }


  43. void get_group_unicode_gb2312(void)
  44. {
  45.     for (int i = 0; i<MAX_UNI_INDEX;i++){
  46.         for (int j = 0; j < MAX_UNI_INDEX; j++){
  47.             if (sort_result[j] == i){
  48.                 uint16_t tmp_gb2312 = p_table_gb2312_to_unicode[2 * j + 1];

  49.                 uint8_t tmp_h_8 = tmp_gb2312 >> 8;
  50.                 uint8_t tmp_l_8 = tmp_gb2312 & 0xFF;

  51.                 //find sort
  52.                 table_sorted_unicode[i] = p_table_gb2312_to_unicode[2 * j];
  53.                 table_sorted_gb2312[i] = tmp_gb2312;
  54.             }
  55.         }
  56.     }

  57. }


  58. void printf_to_file(void)
  59. {
  60.     int file_write = fopen("test.c","w");


  61.     fprintf(file_write,"uint16_t const sorted_unicode[MAX_UNI_INDEX]]={\r\n");
  62.     for (int i = 0; i < MAX_UNI_INDEX; i++){
  63.         fprintf(file_write, "0x%04X,\n", table_sorted_unicode[i]);
  64.     }
  65.     fprintf(file_write, "};\n\n");


  66.     fprintf(file_write, "uint16_t const sorted_gb2312[MAX_UNI_INDEX]]={\r\n");
  67.     for (int i = 0; i < MAX_UNI_INDEX; i++){
  68.         fprintf(file_write, "0x%04X,\n", table_sorted_gb2312[i]);
  69.     }
  70.     fprintf(file_write, "};\n\n");
  71.     fclose(file_write);
  72. }

  73. #endif



  74. int quick_find(uint16_t const * p_data, uint16_t unicode, int min, int max)
  75. {
  76.     const int max_serch_cnt_ctrl = 15;
  77.     int ret = -2;
  78.     int mid;
  79.     int i;
  80.     uint16_t cmp_min;
  81.     uint16_t cmp_max;
  82.     uint16_t cmp_mid;


  83.     for (i = 0; i < max_serch_cnt_ctrl; i++){
  84.         cmp_min = p_data[min];
  85.         cmp_max = p_data[max];

  86.         if (cmp_max == unicode){
  87.             ret = max;
  88.             break;
  89.         }
  90.         else if (cmp_min == unicode){

  91.             ret = min;
  92.             break;
  93.         }
  94.         else if (max == min + 1){
  95.             break;
  96.             //return -1;
  97.         }

  98.         mid = (max + min) / 2;

  99.         cmp_mid = p_data[mid];


  100.         if (unicode > cmp_mid){
  101.             min = mid;
  102.             continue;
  103.             //return quick_find(p_data, unicode, mid, max);
  104.         }
  105.         else{
  106.             max = mid;
  107.             continue;
  108.             //return quick_find(p_data, unicode, min, mid);
  109.         }
  110.     }

  111.     return ret;
  112. }


  113. uint16_t const sorted_unicode[MAX_UNI_INDEX];
  114. uint16_t const sorted_gb2312[MAX_UNI_INDEX];

  115. uint8_t buffer[32];


  116. void print_lib_font(uint8_t* pData)
  117. {
  118.     for (int i = 0; i<16;i++){
  119.         for (int j = 0; j < 2; j++){
  120.             for (int k = 0; k<8; k++){
  121.                 uint8_t bit_fix = 0x80 >> k;
  122.                 int tmp = pData[i*2 + j] & bit_fix;

  123.                 if (tmp){
  124.                     printf("#");
  125.                 }
  126.                 else{
  127.                     printf("-");
  128.                 }
  129.             }
  130.         }
  131.         printf("\n");
  132.     }
  133. }

  134. void test_lib(void)
  135. {
  136.     int fp;
  137. //    uint16_t test_1 = 0x3158;    //口

  138.     uint16_t unicode = 0x68EE;    //UNICODE OF "森"
  139.     char c[] = "一";


  140.     int result = quick_find(sorted_unicode, unicode, 0, MAX_UNI_INDEX);

  141.     uint16_t gb2312 = sorted_gb2312[result];

  142.     c[0] = gb2312 >> 8;
  143.     c[1] = gb2312 & 0xFF;

  144.     uint8_t h = c[0] - 0xA0;
  145.     uint8_t l = c[1] - 0xA0;

  146.     int t_1 = ((h - 1) * 94 + (l - 1)) * 32;

  147. //    t_1 = 32;

  148.     fp = fopen("HZK16", "rb");

  149.     fseek(fp, t_1, 0);

  150.     fread(buffer, 32, 1, fp);
  151.     fclose(fp);

  152.     print_lib_font(buffer);
  153. }

  154. int main(int char_c, char** char_v)
  155. {

  156.     //init_sort_result_buffer();

  157.     //sort_form_zero_to_end();

  158.     //get_group_unicode_gb2312();

  159.     //printf_to_file();

  160.     //{ 0x7F36, 0xF3BE },//GB2312:缶

  161. //    int resule = quick_find(table_sorted_unicode, 0x7F36, 0, MAX_UNI_INDEX - 1);

  162. //    printf("\nfind_gb2312_is:0x%04X\nshould be equal to 0xF3BE", table_sorted_gb2312[resule]);

  163. //    printf("缶 is  %x","缶");

  164.     test_lib();


  165. //    system("pause");

  166.     return 0;
  167. }
复制代码




上传的都是验证性的代码,有需要的自行提取了,附件里面是提取好的映射表和HZK16的点阵字库

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

 楼主| 发表于 2014-11-17 10:48:50 | 显示全部楼层
贴的代码里面数组内容是空的,因为这几个数组很大==!  有需要在附件里面可以看,我的环境是VS2013,实际用任何C的环境应该都是可以运行的

出0入4汤圆

发表于 2014-11-17 12:10:57 | 显示全部楼层
刚好需要               

出0入0汤圆

发表于 2014-11-17 15:42:41 | 显示全部楼层
为什么是纯映射 没规律么

出0入0汤圆

 楼主| 发表于 2014-11-17 20:22:30 | 显示全部楼层
山在桥那边 发表于 2014-11-17 15:42
为什么是纯映射 没规律么

因为UNICODE 跟GB2312是两个完全不同的组织做出来的编码,具体细节自己去查了,我只能说我这个办法可以实现,然后需要大约17K的readonly空间

出0入0汤圆

 楼主| 发表于 2014-11-17 20:23:07 | 显示全部楼层

我也是找半天找不到.. 就自己折腾了,分享出来不要重复造轮子呗

出0入0汤圆

发表于 2014-11-17 20:33:05 | 显示全部楼层
有用,我这边用的是反过来的。

出0入0汤圆

 楼主| 发表于 2014-11-17 20:53:20 | 显示全部楼层
gushuailove 发表于 2014-11-17 20:33
有用,我这边用的是反过来的。

嗯,我找到的资源就是按gb2312排序好的,不过我的需求是UNICODE 转gb2312 我就给翻转了

出0入0汤圆

发表于 2014-11-17 21:20:03 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2014-11-17 21:26:57 | 显示全部楼层
mummy108 发表于 2014-11-17 20:53
嗯,我找到的资源就是按gb2312排序好的,不过我的需求是UNICODE 转gb2312 我就给翻转了  ...

可以看看ELM的 FATFS 源代码,里面有,通过二分法查表实现

出0入0汤圆

 楼主| 发表于 2014-11-17 21:34:14 | 显示全部楼层
not_at_all 发表于 2014-11-17 21:26
可以看看ELM的 FATFS 源代码,里面有,通过二分法查表实现

嗯,都是查表二分的话 应该差不多... 就是不好找.. 而且个人不喜欢二维数组..

出0入0汤圆

发表于 2014-11-17 21:51:18 | 显示全部楼层
mummy108 发表于 2014-11-17 21:34
嗯,都是查表二分的话 应该差不多... 就是不好找.. 而且个人不喜欢二维数组..  ...

都是一维数组啊

出0入0汤圆

 楼主| 发表于 2014-11-17 22:01:44 | 显示全部楼层

好吧  我没找到资源... 不过性能上应该差不了多少,而且开源也用二分查表,就说明这个转换还只有二分搞得定 是吧。。。

出10入0汤圆

发表于 2014-11-17 22:01:45 | 显示全部楼层
mark!!!用到GB2312转UNICODE

出0入0汤圆

发表于 2014-11-18 13:17:21 | 显示全部楼层
还没弄过,学习了

出0入0汤圆

发表于 2014-11-18 20:08:47 | 显示全部楼层
mummy108 发表于 2014-11-17 22:01
啊  好吧  我没找到资源... 不过性能上应该差不了多少,而且开源也用二分查表,就说明这个转 ...

对于常规应用,用二分法查表不但效率高,而且程序比较简洁,所以比较通用

出0入0汤圆

发表于 2014-11-21 11:32:11 | 显示全部楼层
了解下实现的思路

出0入0汤圆

发表于 2014-11-21 11:57:43 | 显示全部楼层
java与c通信时需要
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 03:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表