utf-8与gbk互转
来源:互联网 发布:linux ps和netstat 编辑:程序博客网 时间:2024/06/05 17:12
UTF-8:
UTF-8是UCS字符集的另一种编码方式,UTF-16的每个单元是两个字节(16位),而UTF-8的每个单元是一个字节(8位)。UTF-16中用一个或两个双字节表示一个字符,UTF-8中用一个或几个单字节表示一个字符。
可以认为UTF-8编码是根据一定规律从UCS-2转换得到的,从UCS-2到UTF-8之间有以下转换关系:
UCS-2 UTF-8
U+0000 - U+007F 0xxxxxxx
U+0080 - U+07FF 110xxxxx 10xxxxxx
U+0800 - U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
例如“啊”字的UCS-2编码是0x554A,对应的二进制是0101 0101 0100 1010,转成UTF-8编码之后的二进制是1110 0101 10 010101 10 001010,对应的十六进制是0xE5958A。
#include<stdio.h>
#include<string.h>
int UnicodeToUtf8(char* pInput, char *pOutput)
{
int len = 0; //记录转换后的Utf8字符串的字节数
while (*pInput)
{
//处理一个unicode字符
char low = *pInput;//取出unicode字符的低8位
pInput++;
char high = *pInput;//取出unicode字符的高8位
int w=high<<8;
unsigned wchar = (high<<8)+low;//高8位和低8位组成一个unicode字符,加法运算级别高
if (wchar <= 0x7F ) //英文字符
{
pOutput[len] = (char)wchar; //取wchar的低8位
len++;
}
else if (wchar >=0x80 && wchar <= 0x7FF) //可以转换成双字节pOutput字符
{
pOutput[len] = 0xc0 |((wchar >> 6)&0x1f); //取出unicode编码低6位后的5位,填充到110yyyyy 10zzzzzz 的yyyyy中
len++;
pOutput[len] = 0x80 | (wchar & 0x3f); //取出unicode编码的低6位,填充到110yyyyy 10zzzzzz 的zzzzzz中
len++;
}
else if (wchar >=0x800 && wchar < 0xFFFF) //可以转换成3个字节的pOutput字符
{
pOutput[len] = 0xe0 | ((wchar >> 12)&0x0f); //高四位填入1110xxxx 10yyyyyy 10zzzzzz中的xxxx
len++;
pOutput[len] = 0x80 | ((wchar >> 6) & 0x3f); //中间6位填入1110xxxx 10yyyyyy 10zzzzzz中的yyyyyy
len++;
pOutput[len] = 0x80 | (wchar & 0x3f); //低6位填入1110xxxx 10yyyyyy 10zzzzzz中的zzzzzz
len++;
}
else //对于其他字节数的unicode字符不进行处理
{
return -1;
}
pInput ++;//处理下一个unicode字符
}
//utf8字符串后面,有个\0
pOutput [len]= 0;
return len;
}
/*************************************************************************************************
* 将UTF8编码转换成Unicode(UCS-2LE)编码 低地址存低位字节
* 参数:
* char* pInput 输入字符串
* char*pOutput 输出字符串
* 返回值:转换后的Unicode字符串的字节数,如果出错则返回-1
**************************************************************************************************/
//utf8转unicode
int Utf8ToUnicode(char* pInput, char* pOutput)
{
int outputSize = 0; //记录转换后的Unicode字符串的字节数
while (*pInput)
{
if (*pInput > 0x00 && *pInput <= 0x7F) //处理单字节UTF8字符(英文字母、数字)
{
*pOutput = *pInput;
pOutput++;
*pOutput = 0; //小端法表示,在高地址填补0
}
else if (((*pInput) & 0xE0) == 0xC0) //处理双字节UTF8字符
{
char high = *pInput;
pInput++;
char low = *pInput;
if ((low & 0xC0) != 0x80) //检查是否为合法的UTF8字符表示
{
return -1; //如果不是则报错
}
*pOutput = (high << 6) + (low & 0x3F);
pOutput++;
*pOutput = (high >> 2) & 0x07;
}
else if (((*pInput) & 0xF0) == 0xE0) //处理三字节UTF8字符
{
char high = *pInput;
pInput++;
char middle = *pInput;
pInput++;
char low = *pInput;
if (((middle & 0xC0) != 0x80) || ((low & 0xC0) != 0x80))
{
return -1;
}
*pOutput = (middle << 6) + (low & 0x3F);//取出middle的低两位与low的低6位,组合成unicode字符的低8位
pOutput++;
*pOutput = (high << 4) + ((middle >> 2) & 0x0F); //取出high的低四位与middle的中间四位,组合成unicode字符的高8位
}
else //对于其他字节数的UTF8字符不进行处理
{
return -1;
}
pInput ++;//处理下一个utf8字符
pOutput ++;
outputSize += 2;
}
//unicode字符串后面,有两个\0
*pOutput = 0;
pOutput++;
*pOutput = 0;
return outputSize;
}
//一个调用示例
int main(int argc, char** argv)
{
//汉字“我”的UTF8编码是0xe68891,Unicode编码是 0x6211
//1、unicode转utf8
char unicodeStr[3]={0x11,0x62,0x00};//我的unicode编码是0x6211,按低地址存低位字节
char s[5];
char* utf8Str =s;
memset(utf8Str,0,5);
int num = UnicodeToUtf8(unicodeStr,utf8Str);
unsigned char* p = (unsigned char*)utf8Str;
int i=0;
for(i = 0; i < num; i++)
{
printf("%0x", *p);
p++;
}//输出e68891
printf("\n");
//2、utf8转unicode
char utf8Str1[4] = {0xe6, 0x88, 0x91, 0x00};
char ss[8];
char* unicodeStr1 = ss;
memset(unicodeStr1,0,8);
int num1 = Utf8ToUnicode(utf8Str1, unicodeStr1);
if (num1 == -1)
{
printf("Error!\n");
}
else
{
unsigned char* p = (unsigned char*)unicodeStr1;
int i1=0;
for(i1 = 0; i1 < num1; i1++)
{
printf("%0x", *p);
p++;
}//输出1162
printf("\n");
}
return 0;
}
测试如下:
[root@libmaster bianma]# ./a.out
e68891
1162
- utf-8与gbk互转
- GBK与UTF-8
- GBK与UTF-8
- GBK与UTF-8
- GBK-UTF-8互转
- gbk 与 UTF-8 转换
- GBK与UTF-8区别
- GBK与UTF-8转化
- Android GBK与UTF-8
- UTF-8和GBK互转
- 锟斤拷?UTF-8与GBK互转,为什么会乱码?
- 锟斤拷?UTF-8与GBK互转,为什么会乱码?
- GBK与UTF-8的区别
- UTF-8与GBK之间的区别
- GBK与UTF-8之间的转换
- VC++ UTF-8与GBK格式转换
- gbk与utf-8的区别
- UTF-8与GBK转换程序
- EJB
- 出现No persister for错误后有如下三种解决办法
- Spring Cloud 之 Spring Cloud Zuul(七)
- java中那些关于String的面试题
- mac vscode 配置golang
- utf-8与gbk互转
- 单链表实现及逆序
- spring定时器配置
- 小程序+TP5使用JWT做登陆验证
- Java异常(二)
- 关于用户注册界面测试用例总结(转)
- Linux后台运行命令
- 阻止putty变成inactive
- 关于Oracle误操作--数据被Commit后的数据回退恢复(闪回)