对于Unicode,相信每个javaer都不会陌生。不过对于各种各样的UTF8,UTF16,GBK,GB2312等各种名词,你可能会觉得糊里糊涂,希望读完这篇文章对你有所帮助。
首先我们要清楚一点,Unicode包含Unicode编码和Unicode实现(或者叫传输方式),两者是不同的,而通常我们就最容易搞混这两件事。
Unicode编码的英文缩写是UCS;而Unicode传输方式缩写是UTF。从字面上是不是看出一点点东西?
先来说说UCS。
目前,UCS标准有两种:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,基本上现在用的就是这个标准,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码,是为了防止将来2个字节不够用才开发的。UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。
UCS实际是一种全世界字符编码的“超集”,目标是让全世界所有字符都可以在这套编码里面找到唯一的编码。全世界所有的文字都可以在这些码位上编码,而互不冲突。你可以理解为Unicode组织为各个地区分一些码位范围。按照UCS-2标准,全世界可表示的编码只有65536个码位。可能你会说不够啊,汉字都差不多这个数了。这个我就不清楚了,大概收录的都是常用汉字吧。
再次强调,不管哪一国的字符码均以2个(UCS4是4个)字节表示,在UCS里面的编码都是唯一的,全世界的UCS编码只有一套(当然只有一套,不然怎么叫标准)。
说完UCS,就来说说UTF。为什么有UTF呢?保存UCS不就直接把每个字节都保存下来就OK拉,那需要管那么多。其实我们从“传输方式”字面上就可以看出来,UTF实际上用于传输、保存。
我们可以这样理解,Unicode在内存里,为了快速处理起来,所以定长是可以理解的;但当保存下来的时候,是否定长就是另外一回事了,可能用户更加关注的是文件的大小、传输的快慢等等。
或者说,UCS是你自己系统里面处理Unicode的,不关别人的是,但如果要跟别人交流数据,就要有一定的规范来传输比特流(就是数据啦),这个规范几时UTF。
进一步的,我们甚至可以这样理解,Unicode在内存处理的时候,是定长的,跟UCS对应,但保存成文件的时候(其实就是转化为具体的字节),就用UTF来编码。(可能有误,不过这样会比较好理解。)
目前我们接触比较多的UTF方式有两种UTF-16和UTF-8。UTF-16,顾名思义,就是用16位(两个字节)存储一个UCS-2编码。实际上,这种是最原始的存储方式,把UCS-2直接保存下来,对于少数字符会做一些特殊的处理,不过UTF-16和UCS-2基本上是差不多的。
说到这里,不得不提一下BOM这个东东。例如“汉”字的Unicode编码是6C49,在运算的时候是没什么问题的,直接wchar_t ch = 0x6C49就可以了。但保存成文件就有问题了,究竟是0x6C 0x49(叫Little Endian,低位在前。别搞错,0x6C是低位)还是0x49 0x6C(Big Endian,即高位在前)?于是就有了规定:在UTF-16前面加上两个特殊字符0xFF和0xFE。如果顺序为0xFF 0xFE,那就是就是LE低位在前,否则就是BE高位在前。默认不添加就是指LE。
其实读者可以用WinXP的记事本试试。如下图,ANSI对于我们来说就是GBK,Unicode就是UTF-16(LE),Unicode big endian就是UTF-16(BE),UTF-8当然就是下面即将要介绍的UTF-8。可以把文章保存下来,用不同的编码保存,然后用UE看看十六进制。
虽然有UTF-16,不过欧美就不爽了:凭什么我为了你的汉字要多浪费一倍空间。于是,UTF8就出来了。UTF-8是一种不定长的UTF。UCS-2怎么转换到UTF-8我就不细说了,网上google一大把。下图是UTF-8的分布图,可以看出来,对于传统的ASCII,只需要一个字节,大大节省了空间,不过对于另外一些文字就恰恰相反了,最长的占3个字节。
为了跟好地理解UCS和UTF,读者可以回忆一下在Java里面String跟byte[]的转换:
String s = new String(bytes, “utf-8”);
byte[] bytes = s.getBytes(“utf-8”);
实际上,我们可以这样理解,s对象里面存储的数据,就是UCS,而bytes变量,则是UTF。
说完UCS和UTF,相信读者你已经对Unicode有了各大致的理解了吗?(还没有?对不起,我已经没有存货了。)我们再来聊聊另外一个话题:支持Unicode。
我们经常会听到:java支持Unicode,python也支持Unicode。到底什么是支持Unicode?
我觉得,所谓支持Unicode,无非就是三方面:
(1)有专门的数据类型存储UCS。
(2)方法、函数、相关逐渐支持UCS。
(3)能够正确处理各种UTF。
其实,只要原生字符和字符串是UCS(就是说,用wchar_t表示字符,而不是用char),外加一些处理UTF的函数,其实就相当于支持Unicode了。
看看手表,应该就5分钟啦。
- 大小: 15 KB
- 大小: 13.3 KB
分享到:
相关推荐
2快速入门 2.1Helloworld 2.2国际化支持 2.3方便易用的计算器 2.4字符串,ASCII和UNICODE 2.5使用List 2.6条件和循环语句 2.7如何定义函数 2.8文件I/O 2.9异常处理 2.10类和继承 2.11包机制 总结
最重要的是——请给我30分钟,如果你没有使用正则表达式的经验,请不要试图在30秒内入门——除非你是超人 :) 别被下面那些复杂的表达式吓倒,只要跟着我一步一步来,你会发现正则表达式其实并没有你想像中的那么困难...
用易语言类写的,除了操作系统dll,都是代码,没有模块 ...易语言还是很不错的中文编程,我想是开发工具对中国人来说简单入门简单 这个编辑框功能比较简单 可输入 可选择 可复制 可粘贴 没有双缓冲,所以会闪
json格式数据中,需从'\uxxxx'形式的unicode_escape编码转换成u'\uxxxx'的unicode编码。 7. 自动化测试工具Selenium Selenium是一款自动化测试工具。它能实现操纵浏览器,包括字符填充、鼠标点击、获取元素、页面...
2.Unicode简介 字符集简史 宽字符和WINDOWS 3. 窗口和消息 自己的窗口 WINDOWS程序设计的难点 4. 输出文字 绘制和更新 GDI简介 滚动条 建立更好的滚动 5. 图形基础 GDI的结构 画点和线 绘制填入区域 GDI...
本示例简单演示了如何对一个exe文件的资源操作,没有测试过dll和ocx,只在vista上测试过,其它系统上没有测试过 resattach_detech: 使用vs2008编译,使用了缺省的unicode编码。 作用:把选定的资源加入到指定的exe...
用 易语言 类写的,除了操作系统dll,都是代码,没有模块 ...易语言还是很不错的中文编程,我想是开发工具对中国人来说简单入门简单 这个编辑框功能比较简单 可输入 可选择 可复制 可粘贴 没有双缓冲,所以会闪
它支持普通的转义符清除、Alpha2解密、USASCII解密、Js.Encode解密、字串翻转、Eval等执行解密、XOR枚举、ShellCodeToExe、PDF,CWS,SWF解压、...,同时为了减少操作过程程序同样有简易自动解密和单页自动解密功能...
关键词SEO专家为提高百度、Google、搜狗、搜搜、Bing等的搜索排序结果提供了简单明了的参考数据,支持GB2312和UTF8、Unicode等常用的中文编码方式网页的读取; 同时配合顶尖搜索优化提供的内链和外链分析、IP地址...
包含几个关于socket传输的说明介绍文档,里面有代码 class Server { ... string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead); Console.WriteLine("Received: {0}", msg); // 按Q退出 } }
关键词SEO专家为提高百度、Google、搜狗、搜搜、Bing等的搜索排序结果提供了简单明了的参考数据,支持GB2312和UTF8、Unicode等常用的中文编码方式网页的读取; 同时配合顶尖搜索优化http://www.tseo.cn提供的内链...
2.Unicode简介 …………………… 字符集简史 …………………… 宽字符和C …………………… 宽字符和WINDOWS 3. 窗口和消息 …………………… 自己的窗口 …………………… WINDOWS程序设计的难点 4. 输出...
2. Unicode简介 . 字元集简史 . 宽字元和C . 宽字元和WINDOWS 3. 视窗和讯息 . 自己的视窗 . WINDOWS程式设计的难点 4. 输出文字 . 绘制和更新 . GDI简介 . 卷动列 . 建立更好的滚动 5. 图形基础 ....
原因很简单,16位的Unicode编码可以表示地球人的任何书面语言。这是语言 国际化的一个重要特征。(大家也许见过用中文写脚本,比如:function 我的函数() {} ); Javascript中每个字符都是用2个字节表示的。...
2. Unicode简介 20 字符集简史 21 宽字符和C 27 宽字符和WINDOWS 30 3. 窗口和消息 36 自己的窗口 37 WINDOWS程序设计的难点 57 4. 输出文本 59 绘制和更新 60 GDI简介 63 滚动条 83 建立更好的滚动 92 5. ...