分享
 
 
 

用C语言实现UCS-2和UTF-8之间的互相转化

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

本文简单介绍UCS,UNICODE和UTF-8,并利用C语言实现了UTF-8与UCS2之间的互相转化。

1.什么是UCS和ISO10646?

国际标准ISO10646定义了通用字符集(Universal Character Set, UCS). UCS是所有其它字符集标准的一个超集,它保证也其它字符集双向兼容,即编码间相互转换不会丢失任何信息。UCS字符集U+0000到U+007F与US-ASCII是一致的。

2.什么是UNICODE

历史上, 有两个独立的, 创立单一字符集的尝试. 一个是国际标准化组织(ISO)的 ISO 10646 项目, 另一个是由(一开始大多是美国的)多语言软件制造商组成的协会组织的 Unicode 项目. 幸运的是, 1991年前后, 两个项目的参与者都认识到, 世界不需要两个不同的单一字符集. 它们合并双方的工作成果, 并为创立一个单一编码表而协同工作. 两个项目仍都存在并独立地公布各自的标准, 但 Unicode 协会和 ISO/IEC JTC1/SC2 都同意保持 Unicode 和 ISO 10646 标准的码表兼容, 并紧密地共同调整任何未来的扩展.

3.什么是UTF-8(一种传送和存储格式)

UCS和UNICODE为每个字符分配了一个对应的整数,但并没有明确说明其实现机制.故存在多种编码方式,其中以两个字节和四个字节来存储一个字符的方法分别叫UCS-2, UCS-4,要将一个ASCII文件转换成一个UCS-2文件只要在每个字节前加一个字节0X00,转换成UCS-4只要在每个字节前加三个0X00。

而internet上大量的信息是以ASCII码存在的,如果都用两个字节来存储将浪费大量的资源,同时Unix和Linux下使用USC-2和USC-4会导致严重问题,于是出现了UTF-8(定义于ISO10646-1).

UTF-8(UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters.)

UNICODE(UCS)和UTF-8的对应关系。

U-00000000 - U-0000007F: 0xxxxxxx

U-00000080 - U-000007FF: 110xxxxx 10xxxxxx

U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx

U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

在多字节串中,第一个字节的开头‘1’的数目就是整个串中字节的数目.

下面举UCS-2与UTF-8的对应关系,并利用C语言实现之间的互相转化。

-----------------------------------------------------------------------------------------------------------

| UCS2 | UTF-8 |

|----------------------------------------------------------------------------------------------------------

| | code | 1st Byte | 2nd byte | 3rd Byte |

|--------------------------------------------------------------------------------------------------------

| 000000000aaaaaaa | 0000 - 007F | 0aaaaaaa | | |

|--------------------------------------------------------------------------------------------------------

| 00000bbbbbaaaaaa | 0080 - 07FF | 110bbbbb | 10aaaaaa | |

|--------------------------------------------------------------------------------------------------------

| ccccbbbbbbaaaaaa | 0800 - FFFF | 1110cccc | 10bbbbbb | 10aaaaaa |

|--------------------------------------------------------------------------------------------------------

在这儿我只实现了单个字符的转换,串的转换也是一样的道理。

1,把一个UTF-8字符转换成一个UCS-2字符。

如果转换成功返回1,如果UTF-8字符是一个unrecognized字符,则返回0,且存一个blackbox(U+22e0)到ucs2_code_ptr中。

typedef unsigned short UINT16;

typedef unsigned char UINT8;

typedef unsigned char BOOL;

#define TRURE (BOOL)(1)

#define FALSE (BOOL)(0)

BOOL UTF8toUCS2Code(const UINT8* utf8_code, UINT16* ucs2_code){

UINT16 temp1, temp2;

BOOL is_unrecognized = FALSE ;

UINT16 * in = utf8_code;

if(!utf8_code || !ucs2_code){

return is_unrecognized;

}

if(0x00 == (*in & 0x80)){

/* 1 byte UTF-8 Charater.*/

*ucs2_code= (UINT16)*in;

is_unrecognized = TRUE;

}

else if(0xc0 == (*in & 0xe0) &&

0x80 == (*(in + 1) & 0xc0)

){

/* 2 bytes UTF-8 Charater.*/

temp1 = (UINT16)(*in & 0x1f);

temp1 <<= 6;

temp1 |= (UINT16)(*(in + 1) & 0x3f);

*ucs2_code = temp1;

is_unrecognized = TRUE;

}

else if( 0xe0 == (*in & 0xf0) &&

0x80 == (*(in +1) & 0xc0) &&

0x80 == (*(in + 2) & 0xc0)

){

/* 3bytes UTF-8 Charater.*/

temp1 = (UINT16)(*in &0x0f);

temp1 <<= 12;

temp2 = (UINT16)(*(in+1) & 0x3F);

temp2 <<= 6;

temp1 = temp1 | temp2 | (UINT16)(*(in+2) & 0x3F);

*ucs2_code = temp1;

is_unrecognized = TRUE;

}

else{

/* unrecognize byte. */

*ucs2_code = 0x22e0;

is_unrecognized = FALSE;

}

return is_unrecognized;

}

2,把一个UCS-2字符转换成UTF-8字符。函数返回转换成UTF-8的长度(字节1 -- 3),如果目标指针为空,返回0。

UINT8 UCS2toUTF8Code(UINT16 ucs2_code, UINT8* utf8_code){

int length = 0;

UINT8* out = utf8_code;

if(!utf8_code){

return length;

}

if(0x0080 > ucs2_code){

/* 1 byte UTF-8 Character.*/

*out = (UINT8)ucs2_code;

length++;

}

else if(0x0800 > ucs2_code){

/*2 bytes UTF-8 Character.*/

*out = ((UINT8)(ucs2_code >> 6)) | 0xc0;

*(out+1) = ((UINT8)(ucs2_code & 0x003F)) | 0x80;

length += 2;

}

else{

/* 3 bytes UTF-8 Character .*/

*out = ((UINT8)(ucs2_code >> 12)) | 0xE0;

*(out+1) = ((UINT8)((ucs2_code & 0x0FC0)>> 6)) | 0x80;

*(out+2) = ((UINT8)(ucs2_code & 0x003F)) | 0x80;

length += 3;

}

return length;

}

字符串间的转换也是一样的。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有