Unicode(UTF&UCS)深度历险
Unicode(UTF&UCS)深度历险
计算机网络诞生后,大家慢慢地发现一个问题:一个字节放不下一个字符了!因为需要交流,本地化的文字需要能够被支持。
最初的字符集使用7bit来存储字符,因为那时只需要存下一些英文字母和符号。后来虽然扩展到使用8bit来存储一个字符了(这种方式被国际标准化组织收录,成为ISO8859-1。在字符集发展历程中国际标准化组织一直发挥着重要作用。),也还是无法存储诸如中文的字符。
混乱的年代到来了。为了存储下自己的文字,各个国家和地区(多为非拉丁语系的民族,因为这些语种字符数很庞大)各自使用两个字节即16bit来存放一个字符。他们把首字节的前2^7个位留给一个字节能存下的字符(如英文字母和标点符号),而后的位和后面的字节一起组成适用于本地文字的字符。这中方式一直沿用至今,如GB2312、GBK(此编码为微软为简体中文用户设计的)、GB18030、BIG5等。使用这种方式有一个问题:不同的数值(假如我们把字符换算成数字)在不同的字符集可能有不同的意义,甚至使用不同字体也会呈现出不同的效果!而且从一个字符集到另一个字符集的转化也会非常麻烦!
标准化一直在进行。为了解决上述麻烦,各种机构都做出了不同的努力。以微软为代表的操作系统可能更多的是提供用户可选择的语言和区域设置,并使用如CodePage(代码页,Windows操作系统对不同地区不同字符集的支持方式。如GBK为CP936)来隔离差异,国际标准化组织(ISO)编纂了ISO10646来规范和整合字符集(被成为通用字符集 Universal Character Set,UCS )。统一码联盟(由各个大型企业及组织共同维护)发布了统一码(Unicode)项目。
起初,UCS和Unicode各自为政,但1991年前后他们都发现:世界不需要两个不一样的“统一”、“通用”的字符集。所以他们联合起来维护一个字符集,现在他们的差别大概是发布新版本时使用什么字体了-_-。
UCS和Unicode都使用最大32bit来存储字符,他们(其实是一样的,不过还是区分一下)的码位(字符数)有1114112个,从0x0到0x0x10FFFF。
大家可能会奇怪,32bit最多可以表示超42亿个字符(即从0x0到0xFFFFFFFF),为什么只使用了其中这么小一部分呢?其实,这里面还有一些其他原因。
使用32bit来存储字符看起来是一件一劳永逸的方式,但如果这32bit是定宽的(即任何字符都要使用完这32bit)的话就不可避免的造成空间的浪费,程序效率也会降低!
能不能把UCS(Unicode)设计成“变宽”的呢?聪明的设计师想到了一个主意,他们发明了一种名为“统一码转换格式”即UTF的来将字符对应的数字(可能从小于127至大于100万不等)转化为多个字节来进行存储。
简单说来,UCS或Unicode只是定义了从0到1114112这些数字各自是什么字符。而如果从1~4个字节(变宽)还原出这个数字(或字符)就是UTF的事儿了。
比如“汉”字,对应数字为23383,那么要使用3字节的UTF8格式字节进行存储(原因我们下面再讲),或者1字节的UTF16或1字节的UTF32。
“汉” UTF8 = {0xE6, 0xB1, 0x89}
UTF16 = {0x6c49}
UTF32 = {0x6c49}(高位补0可省略)
Unicode字符集的划分大概有两种:按“单元(Cell)”划分(Unicode官方文档是这样分的)和按“平面(Plane)”划分。一个单元为128个字符,一个平面有65536个字符。
我们通常使用的一个平面取值为0x0到0xFFFF,这个平面被成为BMP(Basic Multilingual Plane)即“平面0”。由于这个平面只是用两个字节就可以完整表示,字符集又可以成为UCS-2(即使用2字符的“通用字符集”,UCS-4即为4字节,将UCS-4的高两位去除即为UCS-2)。
我们常用的27973个汉字都存放与平面0上,整个Unicode共定义了71226个汉字(Unicode5.0.0),平面2的43253个字符都是汉字。
UTF之间的关系和转换。上文说道,“汉”字需要3个UTF8字节来存储,这是因为要符合UTF格式的规范。
一个模版可以告诉我们UTF8是怎样存储数据的:
|
Unicode编码(16进制)
|
UTF-8 字节流(二进制)
|
|
000000 - 00007F
|
0xxxxxxx
|
|
000080 - 0007FF
|
110xxxxx 10xxxxxx
|
|
000800 - 00FFFF
|
1110xxxx 10xxxxxx 10xxxxxx
|
|
010000 - 10FFFF
|
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
可以看到,如果使用两个字节来存储数据,UTF8最多可以存储2^11个字符,最大的数字为0x7FF即2047,显然无法存下数字为23383的“汉”字。
而通过模版我们也可以看出Unicode的最大bit数为21。
数字向UTF的转换也很简单了,把数字换成二进制(不足21位的高位补0),然后填入对应UTF的模版(UTF16和UTF32的模版大家请自行查看,LE和BE区别在于高位和低位的位置,Windows和Linux为LE,MacOS为BE)中替换xxxxxxx就行了!很简单吧。
UTF在文件中的存储。UTF格式在文件中总有固定文件头:
|
UTF编码
|
Byte Order Mark
|
|
UTF-8
|
EF BB BF
|
|
UTF-16LE
|
FF FE
|
|
UTF-16BE
|
FE FF
|
|
UTF-32LE
|
FF FE 00 00
|
|
UTF-32BE
|
00 00 FE FF
|
如“汉”字在文件中的存储(不包括头):
|
Unicode编码
|
UTF-16LE
|
UTF-16BE
|
UTF32-LE
|
UTF32-BE
|
|
0x006C49
|
49 6C
|
6C 49
|
49 6C 00 00
|
00 00 6C 49
|
各个系统和语言对Unicode的支持:
Windows NT从底层支持Unicode(不幸的是,Windows 98只是小部分支援Unicode)。先天即被ANSI束缚的C程序设计语言通过对宽字元集的支持来支持Unicode。
Windows底层使用UTF16,Linux使用UTF32(未考证)。
C#和Java支持UTF16且是默认行为(如字符串天生为UTF16格式字符数组,Java还可以使用'\uxxxx'格式声明一个字符)。
XML及其子集HTML对UTF16支持很好,为跨平台你可以使用'&#xxxx;'来声明一个字符。
欢迎您移步我们的交流群,无聊的时候大家一起打发时间:
或者通过QQ与我联系:
(最后编辑时间2013-09-15 12:22:38)
Unicode(UTF&UCS)深度历险的更多相关文章
- 字符集和编码——Unicode(UTF&UCS)深度历险
计算机网络诞生后,大家慢慢地发现一个问题:一个字节放不下一个字符了!因为需要交流,本地化的文字需要能够被支持. 最初的字符集使用7bit来存储字符,因为那时只需要存下一些英文字母和符号.后来虽然扩展到 ...
- 各个系统和语言对Unicode的支持 字符集和编码——Unicode(UTF&UCS)深度历险
http://www.cnblogs.com/Johness/p/3322445.html 各个系统和语言对Unicode的支持: Windows NT从底层支持Unicode(不幸的是,Window ...
- SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)
接上一篇 SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP 本文采用强制的CGLB代理方式 Security ...
- SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP
AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...
- 分布式Redis深度历险-Cluster
本文为分布式Redis深度历险系列的第三篇,主要内容为Redis的Cluster,也就是Redis集群功能. Redis集群是Redis官方提供的分布式方案,整个集群通过将所有数据分成16384个槽来 ...
- 分布式Redis深度历险-复制
Redis深度历险分为两个部分,单机Redis和分布式Redis. 本文为分布式Redis深度历险系列的第一篇,主要内容为Redis的复制功能. Redis的复制功能的作用和大多数分布式存储系统一样, ...
- Redis深度历险——核心原理与应用实践
高可用架构」的各位老铁们,你们好!你是否还记得上个月发布的文章中,有两篇深入讲解Redis的文章,分别是和,广大粉丝读者们对这两篇文章整体评价颇高.而我就是这两篇文章的原创作者「老钱」(钱文品),我是 ...
- 文字编码ASCII,GB2312,GBK,GB18030,UNICODE,UCS,UTF的解析
众所周知,一个文字从输入到显示到存储是有一个固定过程的,其过程为:输入码(根据输入法不同而不同)→机内码(根据语言环境不同而不同,不同的系统语言编码也不一样)→字型码(根据不同的字体而不同)→存储码( ...
- ASCII UNICODE UTF "口水文"
最近接了一个单是需要把非 UTF-8 (No BOM)编码的文件转换成 UTF-8 (No BOM),若此文件是 UTF-8 但带有 BOM ,需要转换成不带 BOM 的.于是开启了一天的阅读.首先花 ...
随机推荐
- jquery插件之DataTables 参数介绍
DataTables(http://www.datatables.net/)应该是我到目前为止见过的,功能最强大的表格解决方案(当然,不计算其它整套框架中的table控件在内). 先把它主页上写的特性 ...
- 多层次的Json字符串转化为对象
using Arvato.CRM.DataTrans.ConsoleHost.Model;using System;using System.Collections.Generic;using Sys ...
- iOS10收集IDFA,植入第三方广告[终结]--ADMob
[PS: 前段时间,公司做ASO推广,需要在应用中收集IDFA值,跟广告平台做交互!于是有了这个需求--] 1.首先,考虑了一下情况(自己懒 -_-#),就直接在首页上写了一个Banner,循环加载广 ...
- 【转】UiAutomator简要介绍
原文地址:http://blog.csdn.net/g19920917/article/details/16131565 3.1.必备条件: 1.JDK 2.SDK(API高于15) 3. ...
- 百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法
原文:百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法 公司的网站改版要求在一个页面显示百度地图.上面要同时显示很多标注点,标注点当然要有提示信息嘛,提 ...
- 在Eclipse下导入vlc-android并编译
在Ubuntu14.04下载好了VLC的源代码后,VLC的Eclipseproject存放在"vlc-android"文件夹 root@dzt-VirtualBox:/home/d ...
- GitHub上整理
GitHub上整理 技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应 ...
- Gimp教程:多图层多渐变的文字效果
这个教程是我在国外的视频网站上学的,制作这个教程也很久了,今天在网盘翻看到这个截图版本,正好整理到博客,方便管理.记得当时花了一下午的时间来边做边截图修改制作,个人觉得这个教程还是很好的,原作者很有创 ...
- SQL Server 性能调优 之运行计划(Execution Plan)调优
运行计划中的三种 Join 策略 SQL Server 存在三种 Join 策略:Hash Join,Merge Join,Nested Loop Join. Hash Join:用来处理没有排过序/ ...
- jquery无缝滚动效果实现
demo如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...