ESP8266接收数据UTF8转换为GBK2312

前言

        通过实验发现,ESP8266从MQTT读取的数据通常为UTF-8编码,但是项目需求,需要将UTF-8转换为GBK2312进行输出。网上资料过于少或者过于复杂。在这里给大家分享一种稍微方便一点的。

代码如下:

utf2gbk2312.c

#include "utf2gbk2312.h"

UnicodeToGbkMap codeMap[] = {
   {0x3001,0xA1A2}, //GB2312:、<br>
	{0x3002,0xA1A3}, //GB2312:。<br>
	{0x00B7,0xA1A4}, //GB2312:·<br>
	{0x02C9,0xA1A5}, //GB2312:ˉ<br>
	{0x02C7,0xA1A6}, //GB2312:ˇ<br>
	{0x00A8,0xA1A7}, //GB2312:¨<br>
	{0x3003,0xA1A8}, //GB2312:〃<br>
	{0x2014,0xA1AA}, //GB2312:—<br>
	{0xFF5E,0xA1AB}, //GB2312:~<br>
	{0x2016,0xA1AC}, //GB2312:‖<br>
	{0x2026,0xA1AD}, //GB2312:…<br>
	{0x2018,0xA1AE}, //GB2312:‘<br>
	{0x2019,0xA1AF}, //GB2312:’<br>
	{0x201C,0xA1B0}, //GB2312:“<br>
	{0x201D,0xA1B1}, //GB2312:”<br>
	{0x3014,0xA1B2}, //GB2312:〔<br>
	{0x3015,0xA1B3}, //GB2312:〕<br>
	{0x3008,0xA1B4}, //GB2312:〈<br>
	{0x3009,0xA1B5}, //GB2312:〉<br>
	{0x300A,0xA1B6}, //GB2312:《<br>
	{0x300B,0xA1B7}, //GB2312:》<br>
	{0x3016,0xA1BC}, //GB2312:〖<br>
	{0x3017,0xA1BD}, //GB2312:〗<br>
	{0x3010,0xA1BE}, //GB2312:【<br>
	{0x3011,0xA1BF}, //GB2312:】<br>
    //省略一些

};

#define MAP_SIZE (sizeof(codeMap) / sizeof(UnicodeToGbkMap))


// 从映射表中查找GBK编码
uint16_t unicodeToGbk(uint16_t unicode) {
    for (int i = 0; i < MAP_SIZE; i++) {
        if (codeMap[i].unicode == unicode) {
            return codeMap[i].gbk;
        }
    }
    return 0x3F3F; // "??"表示未知字符
}

// 将UTF-8编码解析为Unicode码点
uint16_t utf8ToUnicode(const char *utf8Str, int *bytesProcessed) {
    uint16_t unicode = 0;
    uint8_t c = utf8Str[0];

    if ((c & 0x80) == 0) {  // 单字节UTF-8 (ASCII)
        unicode = c;
        *bytesProcessed = 1;
    } else if ((c & 0xE0) == 0xC0) {  // 双字节UTF-8
        unicode = ((utf8Str[0] & 0x1F) << 6) | (utf8Str[1] & 0x3F);
        *bytesProcessed = 2;
    } else if ((c & 0xF0) == 0xE0) {  // 三字节UTF-8
        unicode = ((utf8Str[0] & 0x0F) << 12) | ((utf8Str[1] & 0x3F) << 6) | (utf8Str[2] & 0x3F);
        *bytesProcessed = 3;
    }
    return unicode;
}

// 将UTF-8字符串转换为GBK2312字符串,保留英文字符
void utf8ToGbk2312(const char *utf8Str, char *gbkStr) {
    int i = 0, j = 0;
    while (utf8Str[i] != '\0') {
        int bytesProcessed = 0;
        uint16_t unicode = utf8ToUnicode(&utf8Str[i], &bytesProcessed);
        
        if (unicode >= 0x20 && unicode <= 0x7E) {  // 英文字符范围
            gbkStr[j++] = utf8Str[i];
        } else {
            uint16_t gbk = unicodeToGbk(unicode);
            if (gbk != 0x3F3F) {  // 如果是有效的GBK字符
                gbkStr[j++] = (gbk >> 8) & 0xFF;
                gbkStr[j++] = gbk & 0xFF;
            }
        }

        i += bytesProcessed;
    }
    gbkStr[j] = '\0';
}


 utf2gbk2312.h

#ifndef UTFTOGBK2312_H
#define UTFTOGBK2312_H

#include "main.h"


// 简化的Unicode到GBK2312的映射表
typedef struct {
    uint16_t unicode;
    uint16_t gbk;
} UnicodeToGbkMap;


uint16_t unicodeToGbk(uint16_t unicode);
uint16_t utf8ToUnicode(const char *utf8Str, int *bytesProcessed);
void utf8ToGbk2312(const char *utf8Str, char *gbkStr);

#endif

        实现原理大致就是通过把UTF-8编码转换为Unicode,再通过映射表,找到对应的GBK2312编码。

        编码内容过长,不便展示请私聊我获取

        注意事项:由于映射表内容过于多,用于单片机的话需要有足够的空间,或者也可以根据使用情况自行裁剪。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值