Unicode 字符集及UTF-8 UTF-16编码
很久以前发在他处的一篇博文,今天翻出来重新整理了一下
Unicode 字符集 共分为 17 个平面(plane), 分别对应 U+xx0000 - U+xxFFFF 的 code points, 其中 xx := 00 - 10。其中第 0 平面不包含为 UTF-16 编码保留的 U+D800 - U+DFFF。第0平面包含了最常用的字符,被成为 Basic Multilingual Plane 或 BMP (基本多语言平面)。
Unicode 在编码上有多种实现,常见的有 UTF-8, UTF-16, UCS-2(已过时), UTF-32(UCS-4)等。
UTF-8 编码
UTF-8是一种变长、多字节编码方式,可以表示所有Unicode字符码点(code point),并且与ASCII兼容。UTF-8使用字节作编码单元(code unit),用一个或多个字节编码一个Unicode字符,其中使用一个字节编码的字符与 ASCII 相同。UTF-8编码中不同含义的字节模式:
- 0xxxxxxx ASCII字符
- 10xxxxxx 多字节字符的非首编码单元
- 110xxxxx 双字节字符的首个编码单元
- 1110xxxx 三字节字符的首个编码单元
- 11110xxx 四字节字符的首个编码单元
- 111110xx 五字节字符的首个编码单元
- 1111110x 六字节字符的首个编码单元
例如元符号 U+00A5( ¥ ),二进制表示为 10100101,共8位,因为UTF-8编码除首字节外其它字节都必须以 10 开头,所以每字节有效位为6位,那么 U+00A5 的最后一个字节应该是 10 100101,此外还剩下的两个比特位由双字节字符的首字节模式 110xxxxx 即可完全容纳。 因些U+00A5 符合双字符编码要求,编码结果为 11000010 10100101 即 0xC2B5。
可以看到 UTF-8 实际上是比较浪费空间的,理论上非首编码单元完全可以不必使用固定的 10 前缀,而是利用整个编译单元保存8位字符数据,从而大大减小编码结果的体积。但UTF-8选择了牺牲空间利用率来换取更高的容错能力,当一大段 UTF-8 编码的内容中出现一两个字节的错误时,解码器可以快速跳过错误字符,找到下一个字符的编码首字节(必定以 110, 1110, 11110, .... 打头)
注:一些 Windows 程序在保存 UTF-8 编码文本文件时会在开头添加 0xEF, 0xBB, 0xBF 序列(貌似这个序列在little-endian与big-endian的机器上顺序还是相反的),一般称为 UTF-8 BOM (Byte Order Mark),当然事实上其与字节顺序无关 -- 因为 UTF-8 本身就以字节为单元 -- 而是用于推断文件的编码方式是否为 UTF-8的。 标准并未规定UTF-8这种文件头标识方式,而BOM在标准中是用来判定UTF-16的字符顺序的(而不是编译方式本身,详见下文)。 但由于微软大力推行这种标记方式,致使行业中的各种解码程序不得不与之兼容。
UTF-16
UTF-16 也是变长多字节编码,并可表示所有 Unicode 字符码点(code point),但以双字节(字)为编码单元。UTF-16的编码原则如下:
- BMP: 使用一个双字节编码单元,字符码点(code point)的数字值与编码单元的数字值相等一一对应。
- 平面 1-10: 使用两个编码单元共四个字节表示一个字符,规则如下:
- 字符值减去 0x10000, 结果为 0 - 0xFFFFF 之间20位长的数字,我们暂记为 n 吧。
- 取出 n 的前10位,加上 0xD800 结果在 0xD800 - 0xDBFF 之间作为第一个编码单元,也称为前导代理(lead surrogate)。
- 取出 n 的后10位,加上 0xDC00 结果在 0xDC00 - 0xDFFF 之间作为第二个编码单元,也称为断后代理(trail surrogate)。
比如字符 U+00A5( ¥ ),属于BMP,编码后为双字节的 0x00A5。
字符 U+201D3 (”3),二进制 10 0000 0001 1101 0011 ,共14个二进制位,不属于BMP,需要使用两个编码单元(4字节)来编码表示, 根据原则2,201D3 - 10000 = 101D3,20位二进制码为 0001 0000 0001 1101 0011 ,前10位为 0001 0000 00 即 0x40,加上 0xD800 得到 lead surrogate 0xD840;后10位为01 1101 0011即0x1D3,加上 0xDC00 得到 trial surrogate 0xDDD3。最后得到UTF-16编码为 0xD840, 0xDDD3。
UTF-16使用双字节编码单元,因些存在字节顺序的问题,可以使用字节顺序标记(Byte Order Mark 或 BOM)来帮助确定字节顺序,即将一个特殊Unicode字符U+FEFF(零宽不断行空白 Zero-width non-breaking space 或 ZWNBSP)置于第一个真正的字符之前, 如果解码程序以自己假定的字节顺序读到了 U+FFFE (这是个保留的非字符值),解码程序应该尝试进行字节交换。 如果没有检测到BOM,标准要求解码程序默认使用 big-endian, 但实际应用大多假定 little-endian, 因为windows默认这样干。字节顺序也可有通过编码名称 UTF-16BE 和 UTF-16LE 区别。
除UTF-16外,UCS-2也是16位编码单元,但不支持双编码单元组合,也就不能表示所有 Unicode 字符。 目前该编码方式已被标记为过时。
UTF-32/UCS-4
这个就不必细说了,编码结果对应Unicode的code point。
C/C++ 中的字符类型与编码方式 [仅个人理解,有待核实] char 类型的字符串一般以代码文件的编码方式处理,比如 UTF-8 保存的 c 代码文件中的 char 字符串使用 UTF-8 编码;而以 GB18030 编码保存代码文件中的字符串使用 GB18030 编码。 而使用 UTF-16 或其它非ASCII兼容的编码保存的代码文件中的字符编码本人未弄清楚。 wchar_t 类型的字符串以 UTF-16(Windows 下) 或 UTF-32(Unix/Linux下) 编码,常量声明方式为 L"string content",即字符串常量前边加L前缀。
Unicode 字符集及UTF-8 UTF-16编码的更多相关文章
- zzy:java采用的是16位的Unicode字符集作为编码方式------理解
java语言使用16位的Unicode字符集作为编码方式,是疯狂Java中的原话. 1,编码方式只是针对字符类型的(不包括字符串类,数值类型int等,这些只是在解释[执行]的时候放到Jvm的不同内存块 ...
- 刨根究底字符编码之十——Unicode字符集的字符编码方式CEF
Unicode字符集的字符编码方式CEF 一.字符编码方式CEF的选择 1. 由于Unicode字符集非常大,有些字符的编号(码点值)需要两个或两个以上字节来表示,而要对这样的编号进行编码,也必须使用 ...
- 刨根究底字符编码之十——Unicode字符集的编码方式以及码点、码元
Unicode字符集的编码方式以及码点.码元 一.字符编码方式CEF的选择 1. 由于Unicode字符集非常大,有些字符的编号(码点值)需要两个或两个以上字节来表示,而要对这样的编号进行编码,也必须 ...
- Unicode字符集,utf8编码,base64编码简单了解
Unicode字符集,utf8编码,base64编码简单了解 Unicode字符集,ASCII,GB2312编码集合等,类似于不同的字典,不同的字符的编码,类似于字典中的字在哪一个页哪一排. 当不同系 ...
- 多字节字符集与Unicode字符集
在计算机中字符通常并不是保存为图像,每个字符都是使用一个编码来表示的,而每个字符究竟使用哪个编码代表,要取决于使用哪个字符集(charset). 多字节字符集: 在最初的时候,Internet上只有一 ...
- Unicode规范中的BOM 和 ISO8891-1编码
Unicode规范中的BOM Unicode规范中有一个BOM的概念.BOM——Byte Order Mark,就是字节序标记.在这里找到一段关于BOM的说明: 在UCS 编码中有一个叫做" ...
- C语言:Unicode字符集
Unicode 也称为统一码.万国码:看名字就知道,Unicode 希望统一所有国家的字符编码.Unicode 于 1994 年正式公布第一个版本,现在的规模可以容纳 100 多万个符号,是一个很大的 ...
- 《windows核心编程系列》二谈谈ANSI和Unicode字符集 .
http://blog.csdn.net/ithzhang/article/details/7916732转载请注明出处!! 第二章:字符和字符串处理 使用vc编程时项目-->属性-->常 ...
- 关于Unicode字符集
最初的unicode编码是固定长度的,16位,也就是2两个字节代表一个字符,这样一共可以表示65536个字符.显然,这样要表示各种语言中所有的字符是远远不够的.Unicode4.0规范考虑到了这种情况 ...
随机推荐
- Mac下载并编译Google安卓AOSP项目代码
Mac下载并编译Google安卓AOSP项目代码 参考 https://source.android.com/source/index.html 这两天用Mac下载安卓AOSP源码,且把遇到的问题记下 ...
- listView中的button控件获取item的索引
在listview中的listitem设置事件响应,如果listitem中有button控件,这时候listitem就不会捕获到点击事件,而默认的是listitem中的button会捕获点击事件.那么 ...
- angularjs-googleMap googleMap api地址解析与反解析
1.js:根据地址得到经纬度var myplace=$scope.place;//获取输入的地址var geocoder = new google.maps.Geocoder();//创建geocod ...
- Asp.net Mvc4 基于Authorize实现的模块访问权限
在MVC中,我们可以通过在action或者controller上设置Authorize[Role="xxx"] 的方式来设置用户对action的访问权限.显然,这样并不能满足我们的 ...
- &与&
- 【转】iOS-Core-Animation-Advanced-Techniques(三)
原文: http://www.cocoachina.com/ios/20150105/10827.html 专用图层 复杂的组织都是专门化的--Catharine R. Stimpson 到目前为止, ...
- iOS菜鸟之FMDB的二次封装简单易用
闲来无事写点东西,希望大家多多指正! 大家先去git下载FMDB,然后将其中source文件夹中的fmdb文件夹拖入自己的项目中.最后就可以引用下面的代码对fmdb进行一次简单的封装. 这样可以更直观 ...
- 深入理解ReentrantLock
在Java中通常实现锁有两种方式,一种是synchronized关键字,另一种是Lock.二者其实并没有什么必然联系,但是各有各的特点,在使用中可以进行取舍的使用.首先我们先对比下两者. 实现: 首先 ...
- gulp Tips
npm配置相关属性用于寻找全局安装的module npm install --save-dev 本地安装 在gulp.src()里指定取用文件的语法是,在[ ]中以字符串形式填写文件名,用&qu ...
- BTREE与其它索引的优缺点对比
数据库BTree索引.Hash索引.Bitmap位图索引的优缺点 (2016-01-05 17:13:40) 转载▼ 标签: 数据库 索引 mysql oracle 分类: IT http://www ...