7.unicode、ucs以上的编码都是本地化编码, 一国之内还没有问题,但是要跨国,就不行了 。比如汉字,在只有iso-8859系列字符集的电脑上显示就只能是乱码了,要显示汉字,电脑上必须装gb2312或gbk的字符集。有没有一个字符集,能够包含全球所有的字符呢?这就是unicode和ucs
1988年,joe becker 发布了一个草案,提出了“unicode”的概念,他解释说“‘unicode’是一种唯一的、统一的、全球的编码”。后来,rlg、sun、microsoft、next(乔布斯被赶出苹果后创建的公司)的人也都逐渐加入到unicode工作组里。1991年1月3日,unicode联盟组织成立,同年发布了unicode1.0.
同时,iso组织也在做同样的事情,创造一个全球统一的字符集(universal coded character set,简称ucs),1993年发布了标准iso 10646-1。
后来,两个组织认识到,世界不需要两个不兼容的字符集,于是,开始合作。从unicode2.0开始,开始采用和ucs相同的字库和字码。这样,两个项目仍都存在,并独立地公布各自的标准。但双方都同意保持两者标准的码表兼容,并紧密地共同调整任何未来的扩展。所以,现在说到ucs字符集,跟unicode可以看成一回事。
unicode编码包含两个层次:第一层定义字符的数值和第二层 定义数值的实现方式 。unicode用数字 0x0~0x10ffff 表示所有字符,所以最多可以容纳 1114112 个字符。 数值的编码方式,也就是实现方式包括 utf-8,utf-16,utf-32 三种 。
有人会说,unicode不是两个字节表示字符的码?为什么数值可以到0x10ffff,这不21位,两个半字节还多了吗?其实,这是混淆了unicode的数值定义和实现,这根本就是两个概念,unicode到底用几个字节表示,取决于其实现方式是utf-8,utf-16,还是utf-32.
比如,“汉字”对应的unicode值是0x6c49和0x5b57,而编码实现是:
char data_utf8[]= {0xe6,0xb1,0x89,0xe5,0xad,0x97}; //utf-8编码 char16_t data_utf16[]= {0x6c49,0x5b57}; //utf-16编码 char32_t data_utf32[]= {0x00006c49,0x00005b57}; //utf-32编码
utf-8utf,全称“unicode transformation formats”。是unicode的编码格式。
utf-8是使用8-bit为单位,对unicode进行编码的。特点是,对不同范围的字符使用不同长度的编码。
unicode编码(十六进制)utf-8 字节流(二进制)
00000000 - 0000007f 0xxxxxxx
00000080 - 000007ff 110xxxxx 10xxxxxx
00000800 - 0000ffff 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001fffff 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03ffffff 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7fffffff 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
utf-8 的编码规则很简单: 如果只有一个字节,那么最高的比特位为 0;如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头 。具体的表现形式为(xxx 就用来存储 unicode 中的字符编号):
0xxxxxxx:单字节编码形式,这和 ascii 编码完全一样,因此 utf-8 是兼容 ascii 的;110xxxxx 10xxxxxx:双字节编码形式;1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式;11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式。下面是一些字符的编码实例(绿色部分表示本来的 unicode 编号):
字符næ齐
unicode 编号(二进制) 01001110 11100110 00101110 11101100
unicode 编号(十六进制) 4e e6 2e ec
utf-8 编码(二进制) 01001110 11000011 10100110 11100010 10111011 10101100
utf-8 编码(十六进制) 4e c3 a6 e2 bb ac
utf-8编码的最大长度是6个字节。
对于0x00-0x7f之间的字符,utf-8编码与ascii编码完全相同,用1个字节表示,首位为0。对于0x80-0x7ff之间的字符,用2个字节表示,第一个字节前三位“110”为标志位,第二个字节前两位“10”为标志位。剩下的11位用来表示unicode值(7ff最多11位)。同样,utf-8的3个字节,可以表示0x800-0xffff的unicode(最多16位)。utf-8的4个字节,可以表示0x10000-0x001fffff的unicode(最多21位)。 4个字节以内,已经包含了unicode所有字符。5、6个字节表示的已经是非unicode编码范围,属于ucs-4 编码。早期utf-8规范也可以达到6字节序列,不过2003年11月utf-8 被 rfc 3629 重新规范,只能使用原来unicode定义的区域, u+0000到u+10ffff。根据规范,这些字节值将无法出现在合法 utf-8序列中。例1:“汉”字的unicode编码是0x6c49。0x6c49在0x0800-0xffff之间,使用用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将0x6c49写成二进制是:0110 1100 0100 1001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即e6 b1 89。例2:unicode编码0x20c30在0x010000-0x10ffff之间,使用用4字节模板了:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。将0x20c30写成21位二进制数字(不足21位就在前面补0):0 0010 0000 1100 0011 0000,用这个比特流依次代替模板中的x,得到:11110000 10100000 10110000 10110000,即f0 a0 b0 b0。utf-8有两个好处:
1字节字符、2字节字符、3字节字符……的首字节标志位不同,这样可以很清楚的区分一个字节属于1字节字符还是2字节字符,如果一个字节流传输中出现错误,也不会错位,只影响部分字符,根据标志位,很容易找到下个正确字符。兼容ascii码, 英美字符用utf-8可以一个字节表示,所以,www组织选用utf-8作为推荐编码格式。2007年,在互联网上,utf-8格式已经超过了ascii码。utf-16utf-16以2字节为单位,等同于ucs-2.
unicode编码(十六进制)utf-16 字节流(二进制)
00000000 - 0000ffff xxxxxxxx xxxxxxxx
00010000 - 0010ffff 110110yyyyyyyyyy 110111xxxxxxxxxx
unicode值小于等于0xffff的,直接用两个字节表示,超过0xffff的,无法用两个字节表示。使用下面公式编码:
1.计算 u’= u – 0x100002. 将u'写成二进制形式:yyyy yyyy yyxx xxxx xxxx3. 加上标志位,1101 10yy yyyy yyyy 1101 11xx xxxx xxxx:高位代理值为d800,低位代理值为dc00可见,这是4个字节表示,2个6位标志位,20位有效位。因为u最大是0x10ffff,所以u’最大是0xfffff,20位足够表示 。
案例1:
u+0020,这个值的范围在第一部分,即经过utf-16编码后,结果仍然为u+0020,在内存中的顺序为00 20。案例2:
u+12345, 这个值的范围在第二部分,因此需要先减去0x10000,得到0x02345,拆分成高10位00 0000 1000和低10位11 0100 0101。根据上面规则加上特定值后,高位代理值为d808,低位代理值为df45,最终内存中的顺序为d8 08 df 45。bom的含义
bom即byte order mark字节序标记。bom是为utf-16和utf-32准备的,用户标记字节序(byte order)。拿utf-16来举例,其是以两个字节为编码单元,在解释一个utf-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的unicode编码是594e,“乙”的unicode编码是4e59。如果我们收到utf-16字节流594e,那么这是“奎”还是“乙”?
我们先来来看下utf-16-big endian文件格式:
可以看到此时“文件”二字的unicode编码并没有超过0xffff,所以使用两个字节来保存:
而 最早的“fe ff”即为bom标签 。
我们再来看下utf-16-little endian文件格式:
使用的bom标签居然变为了fffe。
unicode规范中推荐的标记字节顺序的方法是bom:在ucs编码中有一个叫做zero width no-break space(零宽度无间断空间)的字符,它的编码是feff。而feff在ucs中是不不能再的字符(即不可见),所以不应该出现在实际传输中。ucs规范建议我们在传输字节流前,先传输字符zero width no-break space。这样如果接收者接收到feff,就表明这个字节流是big-endian的;如果收到fffe,就表明这个字节流是little-endian的。因此字符zero width no-break space又被称为bom。
windows上默认的unicode编码方式就是utf-16,使用wchar_t表示。
utf-32utf-32编码以4字节为单位 。直接把unicode值转为4字节二进制数就是其utf-32编码。等同于ucs-4.
8.base64有的电子邮件系统(比如国外信箱)不支持非英文字母(比如汉字)传输,这是历史原因造成的(认为只有美国会使用电子邮件?)。因为一个英文字母使用ascii编码来存储,占存储器的1个字节(8位),实际上只用了7位2进制来存储,第一位并没有使用,设置为0,所以,这样的系统认为凡是第一位是1的字节都是错误的。而有的编码方案(比如gb2312)不但使用多个字节编码一个字符,并且第一位经常是1,于是邮件系统就把1换成0,这样收到邮件的人就会发现邮件乱码。
为了能让邮件系统正常的收发信件,就需要把由其他编码存储的符号转换成ascii码来传输。比如 , 在一端发送gb2312编码->根据base64规则->转换成ascii码,接收端收到ascii码->根据base64规则->还原到gb2312编码 。
9.big5在台湾、香港与澳门地区,使用的是繁体中文字符集。而1980年发布的gb2312面向简体中文字符集,并不支持繁体汉字。在这些使用繁体中文字符集的地区,一度出现过很多不同厂商提出的字符集编码,这些编码彼此互不兼容,造成了信息交流的困难。为统一繁体字符集编码,1984年,台湾五大厂商宏碁、神通、佳佳、零壹以及大众一同制定了一种繁体中文编码方案,因其来源被称为五大码,英文写作big5,后来按英文翻译回汉字后,普遍被称为大五码。 大五码是一种繁体中文汉字字符集,其中繁体汉字13053个,808个标点符号、希腊字母及特殊符号。大五码的编码码表直接针对存储而设计,每个字符统一使用两个字节存储表示。第1字节范围81h-feh,避开了同ascii码的冲突,第2字节范围是40h-7eh和a1h-feh。因为big5的字符编码范围同gb2312字符的存储码范围存在冲突,所以在同一正文不能对两种字符集的字符同时支持。 big5编码的分布如表1-5所示,big5字符主要部分集中在三个段内:标点符号、希腊字母及特殊符号;常用汉字;非常用汉字。其余部分保留给其他厂商支持。
big5编码推出后,得到了繁体中文软件厂商的广泛支持,在使用繁体汉字的地区迅速普及使用。目前,big5编码在台湾、香港、澳门及其他海外华人中普遍使用,成为了繁体中文编码的事实标准。在互联网中检索繁体中文网站,所打开的网页中,大多都是通过big5编码产生的文档。
总结各种字符编码之间的关系上面关于字符集和编码讲了许多概念,其实归类一下可以这么理解: 首先是单字节字符集:
1、最初美国ansi发明了自己的编码ascii,7-bit足够,这是标准ascii。2、标准ascii码没有西欧国家拉丁文、英镑等字符,各公司、国家开始扩展,形成自己的扩展ascii码字符集,各方混战,不过8-bit也就足够。3、天下分久必合,iso统一了8-bit字符集,叫做iso 8859.但是亚洲国家字符更多,一个字节远远不够,于是用多个字节表示,扩展形成本国字符集,中国gb系列,台湾big5,日本jis……,这些叫做多字节字符集(mbcs),windows中用双字节表示,也叫做(dbcs)。
以上字符都是群雄割据,各自为政,windows为了迎合大家需求,在哪个国家,默认编码就用那个国家的,不过后来不知怎么被误传位ansi编码,其实ansi怎么可能定义世界各国编码,不过可以理解成各编码都是在ansi*础上扩展的,因为都兼容ansi的标准ascii码。
这时,iso再次出手,和unicode联盟携手打造了unicode(ucs),意图一统江湖。unicode确实包罗万象,涵盖了各国字符,于是流行世界。unicode自身只定义了每个字符的数值,真正二进制编码格式却是utf-8,utf-16(ucs-2),utf-32(ucs-4)。
我们下期见。
参考
刨根究底字符编码之五——简体汉字编码方案(gb2312、gbk等)以及全角、半角、cjk
字符集和字符编码
电容充电时间计算公式具体计算
苹果下一代iPad的OLED价格进入最后阶段
机器学习专家贾尼安德加入谷歌
液压油缸综合试验台 液压泵综合试验台比例阀控制放大器
高精度体温传感器已在英国诞生
计算机编码全解析(下)
芯片设计封闭体系和开放体系问题解读
LG电子即将发布的G8 ThinQ新旗舰机曝光采用了刘海屏双摄后指纹设计
PT700绝对压力变送器ofweek mall适用于哪些情况
阻焊油墨入孔解决方案
2016年人工智能与深度学习领域的十大收购
dcs控制系统的基础知识
不容忽视的电机测试细节—控制精度
AR/VR在虚拟直播的角色扮演,会不会迎来第二春发展
阻抗如何用于PCB布局 阻抗与电阻对PCB布局的重要性
Aeroflex 推出 PXI 3030 TD-SCDMA
工信部发布2020年智能制造系统解决方案供应商招标公告
诺基亚10概念设计图曝光:较诺基亚8外观、配置、性能全面升级,情怀依旧
NextInput是世界最佳力量感测按钮的先驱者
通过EtherCAT网络实现对自动化设备进行诊断