UTF-8最多到31位,UTF-16只能编码0x 0~10FFFF,这些编码能力现在看来够用了,但并不保证未来够用。以后unicode如果出现大幅扩充,用UTF-8和UTF-16也要能表示,所以,有了本文所描述的扩展方案。
1
主要针对UTF-16。它有三种模式
xxxxxxxx xxxxxxxx → A模式
110110xx xxxxxxxx → B模式
110111xx xxxxxxxx → C模式
大部分字符用A模式可以描述,对于大于65536的,用BC模式,即一个B表示高位,一个C表示低位。
如果B和C用高和低来理解,就无法理解BBC和BBBC等。所以,应该理解C模式为“终止”,这样一来,就能无限扩充UTF-16的表达能力。
例如,BBBBBC,12字节,能表达60位,在64位计算机上,这算是极限了。
另外,UTF-16规定了U=U’+0x10000,这出现于BC模式,用于把表示范围从0~FFFFF扩充至10000~10FFFF。
在BBC、BBBC、BBBBC等模式中,是否还要加0x10000,有待考虑。出于兼容现在的UTF-16,仅在BC模式下加上0x10000就够了。
2
对于UTF-8,扩充将使它失去一部分优美特性,例如,扩充到8字节时,就成了:
11111111 0xxxxxxx (10xxxxxx)*6
第二字节和单字节模式重复了,分不清是8字节模式的第二字节,还是一个ASCII码,这导致UTF-8不那么优美了。
模仿对UTF-16的扩展方案,对UTF-8进行修改。
0xxxxxxx A模式
10xxxxxx B模式
11xxxxxx C模式
例:
A模式表示一个英文字母。
BC模式表示12位unicode值。
BBC模式表示18位,汉字在此,和传统UTF-8一样。
BBBC模式表示24位,可表达现在所有的unicode值。
BBBBBBBBBC表示60位,运行在64位机上正好。
3
名字:
因为理论上可以无限延长,所以,名字就叫UTF-16.inf和UTF-8.inf。其中inf是无穷的意思。
在64位机上实现的版本,叫做UTF-16.inf64和UTF-8.inf64。它并没有实现任意大整数运算,而是把编码限制在60位。
4
源代码:
UTF-8.inf编码的解码器
//UTF-8.inf解码器
#include<stdio.h>
long f(unsigned char *pc)
{
long ret=0;
S1:
printf("S1\n");
if((*pc & 0x80)==0){
//A
goto SA;
}else if((*pc & 0x40)==0){
//B
goto SBBB;
}else{
//C
goto S_error;
}
SA:
printf("SA\n");
return *pc++;
SBBB:
printf("SBBB,%02x\n",*pc);
printf("ret=%p",ret);
ret<<=6;
ret+=(*pc & 0x3f);//取低6位
printf(" %p\n",ret);
pc++;
if((*pc & 0x80)==0){
//A
goto S_error;
}else if((*pc & 0x40)==0){
//B
goto SBBB;
}else{
//C
goto SC;
}
SC:
printf("SC,%02x\n",*pc);
ret<<=6;
ret+=*pc & 0x3f;
return ret;
S_error:
printf("error\n");
return -1;
}
int main()
{
unsigned char str[5]={0x8f,0xbb,0xff,0x00};
long ret=f(str);
printf("值=%p\n",ret);
return 0;
}
/*
UTF-8.inf的BOM是多少?
FE FF,16位,BBC模式
00.1111.1110.1111.1111
001111.111011.111111
10001111.10111011.11111111
8F BB FF
*/
函数里实现了一个有限状态机。