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. 第九节:ASP.NET Core 中多环境的使用

    一. 环境相关配置 1. 说明 ASP.NET Core 在应用启动时读取环境变量 ASPNETCORE_ENVIRONMENT, ASPNETCORE_ENVIRONMENT 可设置为任意值,但框架 ...

  2. 『正睿OI 2019SC Day2』

    分治 普通分治 普通分治是指针对序列或平面问题的分治算法. 思想 普通分治的思想是指将一个序列问题或平面问题通过某种划分方式划分为若干个子问题,直到子问题规模足够小,可以直接回答,再通过合并得到原问题 ...

  3. vs2017专业版和企业版的密钥

    Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH

  4. java基础 抽象

    /** * 抽象方法:就是加上abstract关键字,并去掉大括号,分号结束 * 抽象类:抽象方法坐在的类,必须是抽象类.在class前家abstract即可 * * 如何使用抽象类和抽象方法: * ...

  5. C#读写修改设置调整UVC摄像头画面-全景

    有时,我们需要在C#代码中对摄像头的全景进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...

  6. C# vb .net图像合成-合成椭圆

    在.net中,如何简单快捷地实现图像合成呢,比如合成文字,合成艺术字,多张图片叠加合成等等?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码 ...

  7. .net core Identity注册用户 出错

    使用微软自带的注册 报 NotSupportedException: No IUserTwoFactorTokenProvider<TUser> named 'Default' is re ...

  8. HDU2577 How to Type

    题目链接 一道DP问题 定义dp[i][j]为敲完第i个字母的最小花费,j=1代表Caps Lock打开,j=0代表Caps Lock关闭,则有: 如果第i个字母为大写: dp[i][1]=min(d ...

  9. Django--FBV + CBV

    目录 FBV + CBV FBV(function bases views) FBV中加装饰器相关 CBV(class bases views) CBV中加装饰器相关 FBV + CBV django ...

  10. Spring Boot 框架下使用MyBatis访问数据库之基于XML配置的方式

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...