细说Unicode(一) Unicode初认识
https://segmentfault.com/a/1190000007992346
细说Unicode(一) Unicode初认识
网站开发中经常会被乱码问题困扰。知道文件编码错误会导致乱码,但对其中的原理却知之甚少。偶然从某篇文章了解了Unicode,发现从这条线出发也牵引出了一系列缺失的知识点。通过研读文章,基本了解了一些以前不明白的问题,所以整理了几篇,从几个角度介绍下Unicode, 并聊聊一些相关的问题。
ASCII
上世纪60年代,美国人采用了一种编码来表示英语以及各种符号,该编码方式只有一个字节,能表示256(2^8)个字符。至今为止才定义了128个字符。包括33个控制字符和95个可显示字符,这些可显示字符涵盖了大小写英文字母和一些符号,这就是大名鼎鼎的ASCII编码。
GB 2312
然而随着计算机的发展,各个国家的语言符号多不胜数,在中国光中文字符就有7000多个,还不包括繁体中文,ASCII显然无法满足这么多字符编码需求。所以中国人自己创造了一种字符编码,每个汉字和符号用两个字节来表示。第一个字节称为"高位字节",第二个字节称为"低位字节"。高位字节使用了0xA1 - 0xF7, "低位字节"使用了0xA1 - 0xFE。同时该编码方式兼容了ASCII的编码,对于小于127的字符即0x00 - 0x7F的字符予以保留。这种编码方式就是中文编码GB 2312。
GBK
然而GB 2312能表示的文字也比较有限,对于一些人名,古汉语和繁体字也无能为力。所以我们改进了GB 2312的编码方式,扩展了GB 2312 中不使用的字节,使其同时包括了GB2312的所有内容,又新增了近20000个新的汉字,包括繁体字。该编码就是我们熟悉的GBK。后来由于又加了少数名族的文字,又推出了GB18030,用于取代GBK。而目前为止我们使用最广泛的中文编码还是GBK。
Unicode
再后来,由于不同的国家地区之间都使用不同的编码,导致计算机文件的读取都需要安装不同的解码软件。经常照成文件读取乱码。于是有一些组织决定制定出一个方案,通过统一的编码解决这个难题。于是其中一个团队发明了UCS编码,还有另一个团队发明了Unicode。后来两者达成一致,只发布一套字符集,那就是Unicode 。而UCS的码点将与Unicode保持一致。
Unicode最初规定用16位的编码空间,这16位编码空间称为统一码。这样理论上一共最多有2^16(65536)个字符。基本满足各种语言的使用。实际上当前版本的统一码并未完全使用这16位编码,而是保留了大量空间以作为特殊使用或将来扩展。
目前的Unicode字符分为17组编排,每组称为一个平面(Plane),而每平面拥有65536(即2^16)个码点。上述16位统一码字符称为基本多文种平面(BMP),写成16进制就是从U+0000到U+FFFF。 剩下还有16个辅助平面(SMP),码点范围从U+010000一直到U+10FFFF。这17个平面结合起来至少需要占据21位的空间(2^16 x 2^5),也就是差不多3个字节(24位),而辅助平面实际上是用4个字节表示,方便以后向后扩展。
上面讲到的几种编码都是编码方式,规定了从码点到字符的映射关系,例如 Unicode中U+0061 对应的就是小写字母 "a", 我们可以在浏览器控制台中输入码点查找对应的字符:
UTF
Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)。
网页开发中比较熟悉和常用的编码实现是UTF-8。那么这种实现方式有什么优势呢?UTF-8是一种变长的编码方法。字符长度从1字节到4字节不等。最前面的128个字符,只使用1个字节表示,延续了ASCII的用法。其他分段的字节数如下:
计算机在读取数据的时候都是从高位到地位或从地位到高位。当计算机读到一个3字节字符时,怎么判断是输出1位字符,还是继续读取接下来的2位并合并为一个字符呢?这就要涉及到UTF-8的具体实现了。
UTF-8是这样做的:
单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;
n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,这n个字节的其余空位填充该字符unicode码,高位用0补足。
这样就形成了如下的UTF-8标记位:
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
当读到第一位时,发现是0开头,就读一个字节。发现是110,就读两个字节,发现是1110就读三个字节,以此类推,再根据Unicode规则找到对应的符号输出。这种变长的编码方式,能根据字符采用不同位数的码点,能够有效减少文件的体积。
如果采用Unicode的编码方式直接作为实现方法。那么每个字符都是定长的码点,对于只需要一个字节的字符,需要在前面补0. 这样就照成了空间的浪费,文件就会变大。
UTF编码除了UTF-8,还有UTF-16:最小的码点为2个字节;UTF-32:每个码点固定用4个字节表示。由于UTF-32传输场进下会照成文件空间浪费,HTML5标准规定,网页不得编码成UTF-32。
关于Unicode的介绍就到这。UCS的相关知识,将在下一章结合JavaScript一起讲到。
参考文章:
https://zh.wikipedia.org/wiki
http://www.ruanyifeng.com/blo...
https://www.zhihu.com/questio...
细说Unicode(一) Unicode初认识的更多相关文章
- js 中文汉字转Unicode、Unicode转中文汉字、ASCII转换Unicode、Unicode转换ASCII、中文转换&#XXX函数代码
最近看不少在线工具里面都有一些编码转换的代码,很多情况下我们都用得到,这里脚本之家小编就跟大家分享一下这些资料 Unicode介绍 Unicode(统一码.万国码.单一码)是一种在计算机上使用的字符编 ...
- 杂项-Unicode:Unicode
ylbtech-杂项-Unicode:Unicode Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局 ...
- Unicode 与 Unicode Transformation Format(UTF,UTF-8 / UTF-16 / UTF-32)
ASCII(American Standard Code for Information Interchange):早期它使用7 bits来表示一个字符,总共表示27 = 128个字符:后来扩展到8 ...
- Unicode 与 Unicode Transformation Format(UTF-8 / UTF-16 / UTF-32)
ASCII(American Standard Code for Information Interchange):早期它使用7 bits来表示一个字符,总共表示27 = 128个字符:后来扩展到8 ...
- java 中文转Unicode 以及 Unicode转中文
package com.sun; public class Snippet { public static void main(String[] args) { String cn ...
- .net C#实现 中文转Unicode、Unicode转中文 及与js对应关系
中文转Unicode:HttpUtility.UrlEncodeUnicode(string str); 转换后中文格式:"%uxxxx" 举例:"柳_abc123&q ...
- unicode和unicode编码
unicode编码是什么? 这其实是两个问题,unicode 是什么什么?unicode是怎样编码的? What is Unicode? Unicode provides a unique numbe ...
- 细说 unicode 、utf-8 、utf-16、ascii 、gbk 、gb2312
一.计算机的由来 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为”字节“.再后来,他们又做了一些可以处理这些 ...
- UnicodeMath数学公式编码_翻译(Unicode Nearly Plain - Text Encoding of Mathematics Version 3)
目录 完整目录 1. 简介 2. 编码简单数学表达式 2.1 分数 2.2 上标和下标 2.3 空白(空格)字符使用 3. 编码其他数学表达式 3.1 分隔符 强烈推荐本文简明版UnicodeMath ...
随机推荐
- JVM一些问题
1. 类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,他们的执行顺序 答:先静态.先父后子. 先静态:父静态 > 子静态 优先级:父类 > 子类 静态代码块 ...
- 031 Spring Data Elasticsearch学习笔记---重点掌握第5节高级查询和第6节聚合部分
Elasticsearch提供的Java客户端有一些不太方便的地方: 很多地方需要拼接Json字符串,在java中拼接字符串有多恐怖你应该懂的 需要自己把对象序列化为json存储 查询到结果也需要自己 ...
- 如何从0搭建node服务
第一步 首先要搭一个node服务 基于 express 来快速构建node服务 npm install express 安装express 新建一个项目 myapp npm install expre ...
- Java-关于接口调用的处理
前言:这是我的第一篇博文,是我对现在一些接口调用的梳理,写的不好,请见谅. 序:接口无非就是“你调用别人的接口”和“别人调用你的接口”,我会对这两种情况分别的理一下我的思路. 准备:我使用的是Http ...
- 【转载】linux 压缩和解压缩命令gz、tar、zip、bz2
linux系统下压缩解压缩很让人头大,每次都要查命令.转载下方便以后查阅.原文信息如下: 作者:capecape 来源:CSDN 原文:https://blog.csdn.net/capecape/a ...
- 【题解】子序列个数 [51nod1202] [FZU2129]
[题解]子序列个数 [51nod1202] [FZU2129] 传送门:子序列个数 \([51nod1202]\) \([FZU2129]\) [题目描述] 对于给出长度为 \(n\) 的一个序列 \ ...
- 在window中安装Docker,并生成CentOS镜像
下载并安装windows docker 修改镜像本地保存地址
- Java Mockito 笔记
Mockito 1 Overview 2 Maven 项目初始化 3 示例 3.1 第一个示例 3.2 自动 Mock 3.3 Mock 返回值 3.4 Mock 参数 3.5 自动注入 Mock 对 ...
- 动画重定向技术分析及其在Unity中的应用
前言 笔者新的手游项目使用Unity引擎,动画部分要使用重定向技术来实现动画复用.笔者之前在大公司工作的时候对这块了解比较深入,读过Havok引擎在这部分的实现源码,并基于自己的理解,在公司自研的手游 ...
- .net core使用ocelot---第二篇 身份验证
简介原文链接 .net core使用ocelot---第一篇 简单使用 接上文,我将继续介绍使用asp.net core 创建API网关,主要介绍身份验证(authentication )相 ...