底层原理

计算机编码方式杂谈

2017-08-20  本文已影响47人  _烩面_

标题有点大!能总结多少我就总结多少吧。如有错误的地方,望各位看客指正!

对于从事iOS开发的童鞋们来说,UTF-8这个词对大家来说并不陌生:UTF-8是一种编码方式。编码是什么?编码方式又是什么?UTF-8是怎样一种编码方式?与UTF-16和UTF-32编码方式有什么区别?由此拓展,还存在哪些编码方式?不同的编码方式都有什么特点?就以这些问题为切入点,我们来依次展开!

编码是什么?
编码,两个字要分开来理解。编是一个行为,码是编作用的对象。要想编,肯定得有码。码有ASCII码,GB2312码,GBK码,Unicode码等。上面列举的这些码标准其实是一套信息字符与二进制字符串的映射表。例:在ASCII码标准中拉丁字母A与二进制字符串01000001是对应的,其它的拉丁字母与符号相应的也有一个唯一的二进制客串与之对应。计算机不认识字母,也不认识符号,但它能将字母或符号依据码标准转化(转化其实也就是编的过程)成相应的二进制字符串。我们将这个转化过程称为编码。

编码方式是什么?
编码我们知道了,就是将码转化的过程。码以什么算法编以及编的结果就是编码方式。还以拉丁字母A为例:可以将其编成八位的二进制字符串01000001,也可以将其编成十六位的二进制字符串 00000000 01000001。一个是八位的,一个是十六位的,二进制的字符串长度不一样,存储到计算机系统中后占用的内存就不一样了。 这就两种不同的编码方式。

理解了上面两个概念之后,我们就来扩展说一下码和编。先有码,后有编。没有码,你编什么?这话没毛病!


上面提了,码有ASCII码,GB2312码,GBK码,Unicode码等。码(其实这里说成标准码更合适一点,为了呈上启下,我这里依然说成码,下同)是怎么来的呢?

在计算机系统中,所有的信息最终都将以二进制的形式表示并存储。一个二进制位(bit)有0和1两种状态,八个二进制位就能组合出256种状态(2的8次方),如果每一个状态对应一个符号,就能表示256个符号。以此类推,十六个二制位就能表示65,536个字符...

一开始,是没有标准的,处于混战状态。一个字符在一个系统里可能被编成二进制字符串00000001,在另外一个系统里被编成二进制字符串00000002,在各自的系统里,大家用起来挺好,完全没压力啊!但这个字符要是从一个系统被传送到另外一个系统里就读不出来了,因为编码的标准不同。这没法交流嘛!于是,为了避免混乱,更为了交流,有些人就站出来了:大家听我说,咱们不闹了,统一一个标准吧。这样,就有了统一的码。ASCII码是最早的一个标准!

1967年,美国国家标准学会(American National Standard Institute , ANSI )制定了一套统一的ASCII标准码。ASCII码的出现,很好的解决了以西文字符为基础进行交流的国家的计算机通信信息不兼容的问题。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。一开始指定为7位,即含128个字符,后来扩展至8位,可以表示256个不同的字符。

时代在发展,互联网快速全球化!世界上有那么多语言,原有的ASCII码已经不能满足需求,于是各个国家开始制定自己的ASCII版本。就拿我们的汉语来说,我们制定了自己的汉语编码标准GB2312、GBK,这样,我们就能在电脑上使用统一的汉语编码标准用汉语进行愉快的沟通交流了。

其他国家当然也没闲着,都在搞各自的标准码,这么多标准码,也是一团乱麻啊!这时候,又有人站出来喊话了:我来一统江湖吧!Unicode横空出世了!

Unicode 标准为世界上几乎所有的书写系统里所使用的每一个字符或符号定义了一个唯一的数字。不得不说,世界种地的吃瓜群众要想愉快的沟通,这个太有必要了!

下面着重介绍一下我们熟悉的各种码!

ASCII:又称单字节码。因为每个码最多有8位,也就是一个字节大小。其包含大写和小写字母,数字0 到9、标点符号、在美式英语中使用的特殊控制字符、特殊符号字符、外来语字母和图形符号。

GB2312:GB2312共收入汉字6763个和非汉字图形字符682个。GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB 2312。GB2312中每个字符占两个字节,也就是16位。

GBK:GBK是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。GBK编码方案于1995年10月制定, 1995年12月正式发布,目前中文版的WIN95、WIN98、WINDOWS NT以及WINDOWS 2000、WINDOWS XP、WIN 7等都支持GBK编码方案。写在GBK后面的话:如果说GB2312统一了中国,那么GBK就统一了汉字!嘿嘿!自己理解吧!GBK中的字符同样也占两个字节。

Unicode:Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。

Unicode 不是 16 位的编码!它是 21 位的。这 21 位提供了 1,114,112 个码点,其中,只有大概 10% 正在使用,所以还有相当大的扩充空间。

Unicode编码空间被分成 17 个平面(plane),每个平面有 65,536 个字符。0 号平面叫做基本多文种平面(Basic Multilingual Plane, BMP),涵盖了几乎所有你能遇到的字符,除了 emoji。其它平面叫做补充平面,大多是空的。

以上是计算机中非常常用的一些码,当然其他的肯定还有很多,知识有限,又出不去。如果你知道,欢迎在评论区列出!

编码方式
码有了,接下来就是如何用了。于是,各种编码方式就登场了!

UTF-8,UTF-16,UTF-32
一看他们就是UTF家族的!但事实如此吗?
先来看看UTF是个什么鬼?UTF是UCS Transfer Format的缩写,翻成汉语就是UCS传输格式,UCS又是什么鬼?UCS是Universal Multiple-Octet Coded Character Set的缩写,简称UCS,俗称Unicode。所以,UTF-8、UTF-16、UTF-32是编Unicode码的不同方式。的确是一个家族的!它们是对Unicode编码的不同方式!

UTF-32:它在每个码点上使用整 32 位。32 大于 21,因此每一个 UTF-32 值都可以直接表示对应的码点。尽管简单,UTF-32却几乎从来不在实际中使用,因为每个字符占用 4 字节太浪费空间了。(码点:码中每个字符对应一个唯一的二进制字符串,这个二进制字符串就叫做码点)

UTF-16:UTF-16 本身是一种长度可变的编码。基本多文种平面(BMP)中的每一个码点都直接与一个码元相映射。鉴于 BMP 几乎囊括了所有常见字符,UTF-16 一般只需要 UTF-32 一半的空间。其它平面里很少使用的码点都是用两个 16 位的码元来编码的,这两个合起来表示一个码点的码元就叫做代理对(surrogate pair)。

UTF-8:UTF-8也是一种长度可变的编码方式。它使用一到四个[^5]字节来编码一个码点。从 0 到 127 的这些码点直接映射成 1 个字节(对于只包含这个范围字符的文本来说,这一点使得 UTF-8 和 ASCII 完全相同)。接下来的 1,920 个码点映射成 2 个字节,在 BMP 里所有剩下的码点需要 3 个字节。Unicode 的其他平面里的码点则需要 4 个字节。UTF-8 是基于 8 位的码元的,因此它并不需要关心字节顺序(不过仍有一些程序会在 UTF-8 文件里加上多余的 BOM)。有效率的空间使用(仅就西方语言来讲),以及不需要操心字节顺序问题使得 UTF-8 成为存储和交流 Unicode 文本方面的最佳编码。它也已经是文件格式、网络协议以及 Web API 领域里事实上的标准了。

下面介绍一下其他的一些编码!
Base64
Base64是一种用64个字符来表示任意二进制数据的方法。Base64码一共有64个字符,每个字符占6位(2的6次方),在百度百科中你可以查看一下所有的Base64码的字符与二进制字符串的映射关系。
原理就是将原文本编码后的二进制串依次以每6位为一个单位,然后在Base64码表中找出这个二进制串对应的字符,这样以次类推,直到把所有的文本全部转化为Base64码为止。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。

BIG5
Big5是双字节编码。Big5收录的汉字只包括繁体汉字,不包括简体汉字,一些生僻的汉字也没有收录。大陆是简体字的天下,因此这个码标准我们了解一下就好。

下面附上常用的一些字符的Unicode编码范围
26个大写字母编码范围:01000001~ 01011010(65~90)
26个小写字母编码范围:01100001~ 01111010(97~122)
阿拉伯数字编码范围:00110000~ 00111001(48~57)
基本汉字编码范围:0x4E00~ 0x9FA5(19968~ 40869)

由于知识有限,就整理这么多吧!
如果有错误的地方,欢迎指正交流!不喜勿喷!

引用资料:
1 .百度百科
2 .https://www.objccn.io/issue-9-1/

上一篇下一篇

猜你喜欢

热点阅读