一.UTF-16
UTF-16是Unicode的其中一个使用方式。UTF是 Unicode/UCS TransformationFormat,即把Unicode转做某种格式的意思。但是万万不要说UTF-16编码就是Unicode,这是不对的,因为Unicode他是由2个byte组成的,但是大多数UTF-16也是2个byte组成的,也有4个byte组成的,如:中国文字大部份是两字节,有的是四字节(很多人可能没见过,方正楷体S-超大字符集(SIP)这个字体里面存放的都是四字节的字模,可以从http://wyx.nbtvu.net.cn/jmm/Computing/indexComputing.htm下载相关字体)。
二.UTF-16编码
1.Unicode值小于0x10000的用等于该值的16位整数来表示。
2.Unicode值介于0x10000和0x10FFFF之间的,用一个值介于0xD800和0xDBFF(在所谓的高8位区)的16位整数和值介于0xDC00和0xDFFF(在所谓的低8位区)的16位整数来表示。
3.Unicode值大于0x10FFFF不能按照UTF-16进行编码。
16进制编码范围 | UTF-16 表示方法(二进制) | 10进制码范围 | 字节数量 |
00000000---0000 FFFF | xxxxxxxx xxxxxxxx | 0-65535 | 2 |
00010000---0010 FFFF | 110110yyyyyyyyyy 110111xxxxxxxxxx | 65536-1114111 | 4 |
注意:在0xD800和0xDFFF间的值是特别为UTF-16预留,所以不应该将任何字符的值指定为这个区间内的数值.UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节(2字节)储存,但UTF-16却无法相容于ASCII编码。
三.Unicode转UTF-16
将某个字符的Unicode值转换为UTF-16的编码按照以下步骤进行。假设U是给Unicode值,小于x10FFFF。
1) 如果U <0x10000,U的编码就是无符号的十六位整数,值和其本身的值一样,处理结束。
2) 如果U等于或者小于0x10FFFF,则设U' = U -0x10000。此时,U'一定小于或者等于0xFFFFF,也就是说,U'的值不会超过20位。
3)分别初始化2个16位无符号的整数,W1和W2为0xD800和0xDC00。每个整数都有10位可以用来对字符进行编码,正好能容纳U'的20位。
4) 将U'的高10位分配给W1的低10位,将U'的低10位分配给W2的低10位,处理结束。
用数字来表示,第2步到第4步如下所示:
U' = yyyyyyyyyyxxxxxxxxxx
W1 = 110110yyyyyyyyyy
W2 = 110111xxxxxxxxxx
四.Code
下面的code是简单的实现一个Unicode转成UTF-16的功能。没有实现一批批字符的转,把这段code改进一下就可以了。
//-------------------------------------------------------------------------------------------
#include<stdio.h>
#include <stdlib.h>
int main()
{
FILE *out ;
long unicode = 74565;//在这里只拿一个值做个演示0x12345
//U+12345表示为 D8 08 DF 45(UTF-16BE),或者08 D8 45 DF(UTF-16LE)。
long h , l ;
out = fopen("out.txt","wb");
fputwc(L'xFEFF', out);
if (unicode < 0 || unicode>0x10ffff)
{
printf("error!");
}
else
{
if (unicode <0x10000)
{
fwprintf(out,L"%c", unicode);
}
else
{
unicode = unicode - 0x10000 ;
long vh = (unicode & 0xFFC00)>> 10 ;
long vl = unicode & 0x3ff;
h = 0xD800 | vh;
l = 0xDC00 | vl;
fwprintf(out,L"%c",h);
fwprintf(out,L"%c",l);
}
}
}
//-------------------------------------------------------
五.怎麼在Windows上得到一個UTF-16的文本文件
Windows上的记事本,只有这Unicode格式的,ANSI格式,Unicodebig endian格式,UTF-8格式,如下图:
我怎么能得到一个UTF-16的记事本文件,很简单。用UE来实现吧。用UE打开一个记事本文件,SavaAs,就会有很多编码格式让你选择。这里就有UTF-16的几种格式。但是你用记事本另存为,看这个文件的编码的时候,你发现Unicode,其实有一种说法不是很合理就是,在Windows上UTF-16就是Unicode,其实这种说法不合理,但是这样是能在Windows上建立一个UTF-16格式的文件。
六.參考鏈結:http://zh.wikipedia.org/wiki/UTF-16
http://stallman.blogbus.com/logs/41709878.html
NigelYan---2009-09-12