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是这样做的:

  1. 单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;

  2. 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初认识的更多相关文章

  1. js 中文汉字转Unicode、Unicode转中文汉字、ASCII转换Unicode、Unicode转换ASCII、中文转换&#XXX函数代码

    最近看不少在线工具里面都有一些编码转换的代码,很多情况下我们都用得到,这里脚本之家小编就跟大家分享一下这些资料 Unicode介绍 Unicode(统一码.万国码.单一码)是一种在计算机上使用的字符编 ...

  2. 杂项-Unicode:Unicode

    ylbtech-杂项-Unicode:Unicode Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局 ...

  3. Unicode 与 Unicode Transformation Format(UTF,UTF-8 / UTF-16 / UTF-32)

    ASCII(American Standard Code for Information Interchange):早期它使用7 bits来表示一个字符,总共表示27 = 128个字符:后来扩展到8 ...

  4. Unicode 与 Unicode Transformation Format(UTF-8 / UTF-16 / UTF-32)

    ASCII(American Standard Code for Information Interchange):早期它使用7 bits来表示一个字符,总共表示27 = 128个字符:后来扩展到8 ...

  5. java 中文转Unicode 以及 Unicode转中文

    package com.sun; public class Snippet {    public static void main(String[] args) {        String cn ...

  6. .net C#实现 中文转Unicode、Unicode转中文 及与js对应关系

    中文转Unicode:HttpUtility.UrlEncodeUnicode(string str); 转换后中文格式:"%uxxxx"  举例:"柳_abc123&q ...

  7. unicode和unicode编码

    unicode编码是什么? 这其实是两个问题,unicode 是什么什么?unicode是怎样编码的? What is Unicode? Unicode provides a unique numbe ...

  8. 细说 unicode 、utf-8 、utf-16、ascii 、gbk 、gb2312

    一.计算机的由来 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为”字节“.再后来,他们又做了一些可以处理这些 ...

  9. UnicodeMath数学公式编码_翻译(Unicode Nearly Plain - Text Encoding of Mathematics Version 3)

    目录 完整目录 1. 简介 2. 编码简单数学表达式 2.1 分数 2.2 上标和下标 2.3 空白(空格)字符使用 3. 编码其他数学表达式 3.1 分隔符 强烈推荐本文简明版UnicodeMath ...

随机推荐

  1. 039 RabbitMq及数据同步01

    1.RabbitMq (1)问题引出 目前我们已经完成了商品详情和搜索系统的开发.我们思考一下,是否存在问题? 商品的原始数据保存在数据库中,增删改查都在数据库中完成. 搜索服务数据来源是索引库,如果 ...

  2. VisualSVN 新版本终于支持一个解决方案下多workcopy了,并解决了上个版本一个重要BUG

    Multiple working copies within a single solution VisualSVN 7.0 and older require the solution file a ...

  3. ZYNQ笔记(6):普通自定义IP封装实现PL精准定时中断

    软件的定时中断很难控制精准触发沿的位置,可以通过 PL-PS 的中断完成精准的定时中断.PL 的中断通过 Verilog 代码产生,这样紧密结合 PS-PL 的处理,发挥各自的优势. 一.PL 侧定时 ...

  4. - Gradle 翻译 Analyzer APK文件分析 MD

    目录 目录 APK文件分析 使用 APK 分析器分析您的编译版本 查看文件和大小信息 查看 AndroidManifest.xml 查看 DEX 文件 过滤DEX文件树视图 加载 Proguard 映 ...

  5. ASP.NET Core中如何显示[PII is hidden]的隐藏信息

    有时候我们在ASP.NET Core项目运行时,发生在后台程序中的错误会将关键信息隐藏为[PII is hidden]这种占位符,如下所示: 而知道这些关键信息,有时候对我们调试程序是非常重要的.所以 ...

  6. ftp搭建后外网无法连接和访问阿里云服务器(非软件)

    阿里云服务器由于性价比高,是不少企业建站朋友们的首选.而在购买阿里云服务器后,不少客户反映其在搭建FTP后出现外网无法访问的问题,这里特意搜集整理了关于ftp搭建后外网无法连接和访问的问题,提供以下解 ...

  7. Angular复习笔记6-依赖注入

    Angular复习笔记6-依赖注入 依赖注入(DependencyInjection)是Angular实现重要功能的一种设计模式.一个大型应用的开发通常会涉及很多组件和服务,这些组件和服务之间有着错综 ...

  8. Python面向对象之私有属性和私有方法

    01. 应用场景及定义方式 应用场景 在实际开发中,对象 的 某些属性或方法 可能只希望 在对象的内部被使用,而 不希望在外部被访问到 私有属性 就是 对象 不希望公开的 属性 私有方法 就是 对象  ...

  9. 常用模块 - logging模块

    一.简介 logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统.logging模块是Python的一个标准库模块,由标准库模块提供日志记录API的关键好处是所有Python ...

  10. 24、vuex刷新页面数据丢失解决办法

    刷新页面时候将state数据保存到localStorage里面: export default { name: 'App', created () { //在页面加载时读取localStorage里的 ...