HTML与javascript中常用编码浅析(2)
作者:stauren 来源:口碑网UED Team 发布时间:2008-12-23 12:20:00
要把 UTF-8 说清楚,引入一个表会更方便了:
U-00000000 – U-0000007F: 0xxxxxxx
U-00000080 – U-000007FF: 110xxxxx 10xxxxxx
U-00000800 – U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 – U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 – U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 – U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
要看懂这个表呢,我们看前两行就够了
U-00000000 – U-0000007F:
0xxxxxxx 第一行是这样的,意思是说,如果你发现一个utf-8编码的 byte 的二进制码是0xxxxxxx,是0开头的, 即十进制的0-127之间,那么他就是单独的这一 byte 代表一个字符,而且是拥有和 ascii 码完全一样的含义。其他所有的 utf8 编码的二进制值都是用1开头的1xxxxxxx,大于127的,而且都需要至少2 bytes才能代表一个符号。所以一个字节的第一位是一个开关,代表这个字符是不是一个 ascii 码。这个就是刚才谈到的兼容性,从英文定义上看,就是utf8编码的两个属性:
UCS characters U+0000 to U+007F (ASCII) are encoded simply as bytes 0×00 to 0×7F (ASCII compatibility). This means that files and strings which contain only 7-bit ASCII characters have the same encoding under both ASCII and UTF-8.
All UCS characters >U+007F are encoded as a sequence of several bytes, each of which has the most significant bit set. Therefore, no ASCII byte (0×00-0×7F) can appear as part of any other character.
然后我们看看第二行:
U-00000080 – U-000007FF: 110xxxxx 10xxxxxx
先看第一个字节:110xxxxx,它的含义是,我不是一个 ascii 码(因为第一位不为0),我是一个多 bytes 字符的第一个 byte (第二位为1),我参与表示的这个字符是由2个 bytes 组成的(第三位为0),从第四位开始,就是字符的信息储存的位置。
再看第二个字节:10xxxxxx,它的含义是:我不是一个 ascii 码(因为第一位不为0),我不是一个多 bytes 字符的第一个 byte (第二位为0),第三位开始是字符的信息储存的位置。
从这个例子中可以总结出来,utf-8编码方式中,在一长串连续的二进制 byte 码中,可能由2个至6个 bytes 来表示一个符号,那么相比较于用一个 byte 表示符号的 ascii 码,我们需要空间来储存两个额外信息: 一,这个符号开始位置,一个“starter”的位置,用生物学上的话来说,就是蛋白质翻译时候起始密码子AUG的位置了;二,这个符号使用的 bytes 数(其实如果每个符号都有 starter,这个长度是可以不提供的,但是提供长度信息增加了在部分 bytes 丢失时的容错能力)。解决方案是:用一个 byte 的第二位是否是1来代表这一 byte 是否是一个字符的起始 byte (因为一个 byte 里面的第一位刚才已经被使用了,0表示ascii码,1表示非ascii ),即,一个多字节符号的第一 个bytes一定是 11xxxxxx,一个192到255之间的二进制数。接下来,从第三位开始,提供长度信息,第三位是0表示这个符号是2字节的,第三位开始每多一个1,字符占用的 bytes 数加一。utf-8 最多定义到了 6 字节字符,需要比 110xxxxx 这样的表示2字节的starter多 4 个 1,所以这个starter就是 1111110x,如上表所示。
再看看英文定义的标准吧,表达的同样的意思:
The first byte of a multibyte sequence that represents a non-ASCII character is always in the range 0xC0 to 0xFD and it indicates how many bytes follow for this character. All further bytes in a multibyte sequence are in the range 0×80 to 0xBF. This allows easy resynchronization and makes the encoding stateless and robust against missing bytes.
真正的信息位(即,真正的charset字符集中的数字信息),是直接用二进制的方式,依顺序放在上面这个表的’x'上的。用我们中国程序员接触最多的汉字来说吧,它们的编码区间是在 U-00000800 – U-0000FFFF 之间的,从上面的表中可以查到,这个区间的 utf-8 编码是用三个字节来表示的(这就是 utf-8 编码的汉字会比每个字符占用2 bytes的 EUC-CN 编码的 gb2312 字符集的汉字使用更多储存空间的原因),还是用 口碑的”口”字举例吧,口字在 Unicode 中的编号是这样的:
口: 21475 == 0×53e3 == 二进制 101001111100011
在 javascript 中,run这段代码(使用 firebug 的 console,或者编辑一个HTML将下列代码插入一对 script 标签之间):
alert(’\u53e3′); //get ‘口’
alert(escape(’口’)); // get ‘%u53E3′
alert(String.fromCharCode(’21475′)); // get ‘口’
alert(’口’.charCodeAt(0)); // get ’21475‘
alert(encodeURI(’口’)); //get ‘%E5%8F%A3′
可以看到,string直接量可以用\u+十六进制 Unicode 码的形式得到字符 ‘口’,而fromCharCode 方法接受 10 进制的 Unicode 码,得到字符 ‘口’。
其中第二个alert得到的是 ‘%u7545′ , 这是一种不标准的Unicode编码,是属于 URI 的 Percent encoding 一部分,但这种使用方法已经正式被 W3C 拒绝了,任何一个 RFC中都没有这个标准,ECMA-262 标准中规定了 escape 的这种行为,估计也是暂时的。
比较有意思的是第五次alert得到的 ‘%E5%8F%A3′ 这是什么呢?怎么得到的呢?
这就是在URI上用的比较多的 Percent encoding,百分号编码,RFC 3986 标准中规定的。


猜你喜欢
- 从信息组织角度来看,段落内行之间的关系要比段落之间的关系低一个级别,所以在呈现上段落之间的“段距”应该大于段落之内的“行距”,如此才能一目了
- 这些编码,早些时候在一些应用软件中经常看到,估计很多朋友也看到了,这些编码了!从这个图,我们可以看到这类编码应用很广泛,那么我们一起看看,i
- 什么是Tkinter?Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用
- Geany中配置python的方法:一、文件下载并安装1、下载Python下载地址:https://www.python.org/downl
- 本文实例讲述了Python实现的手机号归属地相关信息查询功能。分享给大家供大家参考,具体如下:根据指定的手机号码,查询其归属地等相关信息,P
- 我们通常会通过单击按钮的操作,将定义好的内容直接复制到剪贴板对于用户来说点了按钮直接【Ctrl】+【V】就可以了。其实该功能的核心原理就是用
- // 和PHP一样的时间戳格式化函数// @param {string} format 格式
- 编程语言中反射的概念在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(s
- 最近几天从网上找了几个asp.net的登录案例想要研究研究代码,结果在用Sql Server2005附加数据库文件时弹出错误信息:看到网友回
- Python Dash开发Web应用的控件基础本文主要是通过Dash的Checklist组件,简单介绍使用Dash开发的Web应用展示效果如
- 1 介绍SQL注入漏洞主要是由于,在请求的时候没有做严格的过滤,导致传入的语句被当做SQL语句被执行,从而导致数据库受损(被脱库、删除、甚至
- QQWry.dat数据可以去百度搜索最新版本<%'======================================
- 在通过拼组sql语句来实现数据插入的应用中,我们很有可能会遇到需要插入大型数据的情况,例如,在oracle中需要插入字节数超过4000的字段
- 前言最近接到个任务是抽取mysql和Oracle的元数据,大致就是在库里把库、schema、表、字段、分区、索引、主键等信息抽取出来,然后导
- 上一次,我们谈到在ASP中如何利用“正则表达式”对象来实现各种数据的校验,文中描述了正则表达式对象的强大功能,接下来,我们来看看有关“正则表
- 1. Graphql是什么?GraphQL是Facebook 在2012年开发的,2015年开源,2016年下半年Facebook宣布可以在
- 本文实例讲述了Python使用matplotlib绘制正弦和余弦曲线的方法。分享给大家供大家参考,具体如下:一 介绍关键词:绘图库官网:ht
- 本文实例为大家分享了opencv实现图像缩放效果的具体代码,供大家参考,具体内容如下图像缩放:图像缩放即对图像的大小进行调整,即放大或者缩小
- 现在大多数Centos6.x版本的系统python都是2.x,现因开发需求需要安装前端代码的构建工具glue,故必须要做python版本的升
- “你如何为成千上万的用户和页面提供CSS?” 这是Nicole Sullivan在她的在丹佛的Web Directions North 大会