`
liangguanhui
  • 浏览: 111651 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

五分钟Unicode简单入门

阅读更多

对于Unicode,相信每个javaer都不会陌生。不过对于各种各样的UTF8,UTF16,GBK,GB2312等各种名词,你可能会觉得糊里糊涂,希望读完这篇文章对你有所帮助。

 

首先我们要清楚一点,Unicode包含Unicode编码Unicode实现(或者叫传输方式),两者是不同的,而通常我们就最容易搞混这两件事。

 

Unicode编码的英文缩写是UCS;而Unicode传输方式缩写是UTF。从字面上是不是看出一点点东西?

 

先来说说UCS

 

目前,UCS标准有两种:UCS-2UCS-4。顾名思义,UCS-2就是用两个字节编码,基本上现在用的就是这个标准,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码,是为了防止将来2个字节不够用才开发的。UCS-22^16=65536个码位,UCS-42^31=2147483648个码位。

 

UCS实际是一种全世界字符编码的“超集”,目标是让全世界所有字符都可以在这套编码里面找到唯一的编码。全世界所有的文字都可以在这些码位上编码,而互不冲突。你可以理解为Unicode组织为各个地区分一些码位范围。按照UCS-2标准,全世界可表示的编码只有65536个码位。可能你会说不够啊,汉字都差不多这个数了。这个我就不清楚了,大概收录的都是常用汉字吧。

 

再次强调,不管哪一国的字符码均以2个(UCS44个)字节表示,在UCS里面的编码都是唯一的,全世界的UCS编码只有一套(当然只有一套,不然怎么叫标准)。

 

说完UCS,就来说说UTF。为什么有UTF呢?保存UCS不就直接把每个字节都保存下来就OK拉,那需要管那么多。其实我们从“传输方式”字面上就可以看出来,UTF实际上用于传输、保存

 

我们可以这样理解,Unicode在内存里,为了快速处理起来,所以定长是可以理解的;但当保存下来的时候,是否定长就是另外一回事了,可能用户更加关注的是文件的大小、传输的快慢等等。

 

或者说,UCS是你自己系统里面处理Unicode的,不关别人的是,但如果要跟别人交流数据,就要有一定的规范来传输比特流(就是数据啦),这个规范几时UTF。

 

进一步的,我们甚至可以这样理解,Unicode在内存处理的时候,是定长的,跟UCS对应,但保存成文件的时候(其实就是转化为具体的字节),就用UTF来编码。(可能有误,不过这样会比较好理解。)

 

目前我们接触比较多的UTF方式有两种UTF-16UTF-8UTF-16,顾名思义,就是用16位(两个字节)存储一个UCS-2编码。实际上,这种是最原始的存储方式,把UCS-2直接保存下来,对于少数字符会做一些特殊的处理,不过UTF-16UCS-2基本上是差不多的。

 

说到这里,不得不提一下BOM这个东东。例如“汉”字的Unicode编码是6C49,在运算的时候是没什么问题的,直接wchar_t ch = 0x6C49就可以了。但保存成文件就有问题了,究竟是0x6C 0x49(叫Little Endian,低位在前。别搞错,0x6C是低位)还是0x49 0x6CBig Endian,即高位在前)?于是就有了规定:在UTF-16前面加上两个特殊字符0xFF0xFE。如果顺序为0xFF 0xFE,那就是就是LE低位在前,否则就是BE高位在前。默认不添加就是指LE

 

其实读者可以用WinXP的记事本试试。如下图,ANSI对于我们来说就是GBKUnicode就是UTF-16LE),Unicode big endian就是UTF-16BE),UTF-8当然就是下面即将要介绍的UTF-8。可以把文章保存下来,用不同的编码保存,然后用UE看看十六进制。

 

虽然有UTF-16,不过欧美就不爽了:凭什么我为了你的汉字要多浪费一倍空间。于是,UTF8就出来了。UTF-8是一种不定长的UTFUCS-2怎么转换到UTF-8我就不细说了,网上google一大把。下图是UTF-8的分布图,可以看出来,对于传统的ASCII,只需要一个字节,大大节省了空间,不过对于另外一些文字就恰恰相反了,最长的占3个字节。

 

为了跟好地理解UCSUTF,读者可以回忆一下在Java里面Stringbyte[]的转换:

String s = new String(bytes, “utf-8”);

byte[] bytes = s.getBytes(“utf-8”);

实际上,我们可以这样理解,s对象里面存储的数据,就是UCS,而bytes变量,则是UTF

 

说完UCSUTF,相信读者你已经对Unicode有了各大致的理解了吗?(还没有?对不起,我已经没有存货了。)我们再来聊聊另外一个话题:支持Unicode

 

我们经常会听到:java支持Unicodepython也支持Unicode。到底什么是支持Unicode

 

我觉得,所谓支持Unicode,无非就是三方面:

 

1)有专门的数据类型存储UCS

 

2)方法、函数、相关逐渐支持UCS

 

3)能够正确处理各种UTF

 

其实,只要原生字符和字符串是UCS(就是说,用wchar_t表示字符,而不是用char),外加一些处理UTF的函数,其实就相当于支持Unicode了。

 

看看手表,应该就5分钟啦。

 

  • 大小: 15 KB
  • 大小: 13.3 KB
7
3
分享到:
评论
2 楼 summersmile 2009-12-23  
关于UCS和UTF-8的转换再阐述一下就更好了。
1 楼 starry198804265811 2009-12-23  
以前我太明白UCS和UTF的区别,看了你的文章我知道一些了。

相关推荐

Global site tag (gtag.js) - Google Analytics