你真的理解数码技术吗?(二)

1.2 文字是如何用数字来记录的

在人类创造的各种信息当中,文字信息一直被我们认为是知识和智慧的重要载体,古代无数僧侣和学者,终身都献身于书籍文字的保存和传达。很多书籍靠着一代代人手工抄写而流传下来。然而这种抄写费时费力不算,还常常会导致抄写错误,导致信息的“失真”。也有很多藏书因为保管不善而毁于腐朽或者战火。

在所有需要表达的信息当中,文字是最早被纳入“数字化”的信息种类之一。摩斯电码(Morse Code)是人们发明出来用电信号表达文字的最早方法之一,也是最早的数字化通信形式。通过断的电流,产生一种一系列按顺序排列的“代码”,从而可以用来表达文字。它的代码是:点(.)、划(-)、空(每个字符间的短停顿)、中等时间的空(每个词之间的中等停顿)、长空(每个句子之间的长停顿),如图1-8所示。有两种“符号”用来表示字符:点(.)和划(-),或叫“滴”(Dit)和“答”(Dah)。点的长度决定了发报的速度,并且被当作发报时间参考。这种方法除了可以用在电报上,也可以用于闪光等多种媒介上。

图 1-8 摩斯代码

现代计算机处理文字的方法和摩斯电码有一定的相似,只是用来代表文字的代码不再是点和划,而是真正的数字。一旦文字被计算机数字化之后,我们就拥有了一种永久性保存文字信息和快速、百分百准确的文字复制手段。当我们第一次知道:整个图书馆的书,被数字化后,只需要薄薄的几张光盘——这种载体体积的巨大差异,让我们倍感计算机的神奇。在现代几乎所有的高级编程语言中,字符或者字符串,都作为基本的数据类型存在。

1.2.1 美国信息交换标准代码

计算机界使用的最广泛的,用数字来表示文字的方案,就是如图1-9这个方案。你可以发现这个方案使用了0~127这128个数字,来代表128个字符,其中最常见的就是26个英文字母的大小写,以及10个阿拉伯数字,当然还有一批符号。这些符号中有些可以用键盘直接输入,有些则不能。这个表格,或者方案的名字,就叫做《美国信息交换标准代码》,简称ASCII。这个方案定义了我们在计算机世界中,最常见的英文字母和符号用哪些数字来代表。

图1-9 ASCII编码表

当我们从计算机里得到一串数字的时候,比如从文件里读取到,或者从网络上接受到的。我们完全可以按这个编码表来解读,比如我们可能会获得“72 101 108 108 111”这5个数字的时候,按表查询,就应该是Hello这5个字母。——这个看起来是不是有点像一组密码的解码过程?实际上,如果你在电脑里建立一个文本文件,输入Hello这5个字母然后保存,这个文件的内容就是72 101 108 108 111这5个数字。这和所有的别的文件一样,都只是一般的数字而已。你可以尝试把文件名改成a.exe或者别的什么名字,都不会改变这5个数字的内容。你也可以尝试用你的文本编辑器,在windows下是notepad,Linux下用cat命令,打开任何文件,只要文件里面存放的数字是符合上面这个表格的,都会被显示成对应的文字字符。可以说这个文本编辑器本身的功能,就是把数字转换成文字来显示。

图1-10 文字的数字化表达

这是一篇英文文章(马丁·路德·金《我有一个梦》节选)的txt格式内容,如上图1-10所描述,实际上是一系列的数字组成,需要注意的是,这里的数字是16进制格式显示的数字。在文章中,因为存在很多空格,所以我们很容易分辨出16进制的数字“20”,也就是十进制的数字32,这个数字正式ASCII所规定的数字。

有时候我会想,为什么ASCII中要把文字的“1”定义成49这个奇怪的数字呢?明明数字1代表文字的1不是很自然吗?这个原因我不得而知,但是我知道,如果我们使用不同的编码表来处理同一份数据,结果一定是非常混乱的。比如你用1来表达文字‘1’,我用49来表达‘1’,最后当我收到一个文件,内容是1这个数字的时候,我可能会显示出不是‘1’这个文字的内容。这就跟两种不同语言的人在对话一样。因此文字编码表本身,就是计算机界用来表达文字的语言规范。所以其实具体哪个数字表示哪个字符并不重要,重要的是要统一使用一份相同的编码表。

ASCII编码的顺序规则却是有明显意义的,你会发现0-9的编码是从小到大的,而字母都比数字要大,小写字母比大写字母大,这个编码方式的结果就是,如果你要按我们常见的习惯来对单词排序的话,直接使用这个编码表中的顺序,就可以直接排序了。

现在我们中文的编码表,是按照汉语拼音的排序顺序,来定义各个汉字的编码数字的,所以我们要按拼音排序,就变得异常简单,直接按他们的这些数据的大小排序就可以了!——这真是一件伟大的工作,我每次在使用汉字排序的程序的时候,都会从心底向制定汉字编码的中国科学家发出由衷的致敬。因为汉字有很多多音字,并且数量庞大,如果他的编码不是预先做好了这个排序,要程序员自己去实现这个功能,将是多么大的一个挑战!

1.2.2 乱码

乱码是我们在使用计算机处理文字的时候,最常碰到的问题之一,也是让我们觉得很困惑的事情。为什么我们在技术这么发达的时代,还会在文字这种看似简单的问题上碰到障碍呢?实际乱码的问题揭示了数字技术的一些本质,了解乱码产生的原因,能帮我们理解数字技术的核心概念。乱码的产生有三个原因:

  • 在数据的基本格式——长度分割上就是用了错误的编码规则。我们知道,英文字符一般都是用一个小于255的数字来表示,而中文字符因为远多于255,所以一般都要用2个字符,也就是在0到65535。既然这些数字一个个排列起来,就有可能因为错误的方式被解读——比如前一个汉字的后半部分和后一个汉字的前半部分被看成了一个字。如果你打开一个包含中文的文本文件,然后删除掉第一个中文字的第一个字节,你会发现整个文件的文字都不能正常显示了。这揭示了一个计算机处理文字的原理——所有的那些代表文字的数字,都是被无区别的,按顺序的一个个字节读取然后处理。顺序,是数字化信息中最重要的关键。

——在“黄”字删除掉一个字节的数据后,后面的所有文字都解释错误了,直到一个单字节的数字“06”之后,文字解释恢复了正常

  • 即使使用了相同的长度分割规则,但还是使用了错误的文字内容编码规则。这个最典型的就是gb编码和big5编码的问题。很多时候我们收到一个港澳台地区制作的文本文件,或者浏览这些地区的网站,会发现都是显示出一些奇怪的中文字,这就是因为这些地区的中文,都是用一个叫big5的编码规则来编码中文的,而大陆的电脑基本上都是默认按gb2312编码规则来显示中文,所以就会显示出错误的中文字符来了。
  • 对不是代表文字的数据,按文字的方式来解读。如果你想试验一下这个,可以随便找一个图片文件,或者exe之类的,把文件名改成“x.txt”,然后用notepad(记事本)打开,你通常都会看到“乱码”。实际上在互联网上,很多不是文本格式(也就是说不仅仅包含文字)的页面,都可以在错误的情况下,被浏览器按照文本格式读取,自然就会出现乱码了。这也再一次证明,计算机实际上是“不认识”它要处理的内容的,你命令它以文本编码方式去解码一串数字,它就老老实实的去做了,至于解码出来是什么东西,它是不管的。这必须使用者或者程序员去关心。

计算机无法把文字信息显示出来。要理解这种故障的原因,我们除了了解计算机如果处理文字的编码外,还需要了解计算机是如何显示文字的。实际上任何的文字,都是一张小小的图片。一个横向16个点和纵向16个点的点阵图,就可以表示所有的英文字符和数字,而中文则需要更大更多点的图像来显示。计算机预先会存放所有这些字符的“图形”,然后根据文字的编码,显示出对应的图形。但是如果计算机没有对应编码的图像,就往往会显示出一些奇怪的字符,最常见的就是显示一个“?”来代替。而这些字符对应的一大批的“图形”,我们叫做“字库”。如果你要显示中文,就必须要有中文的字库,否则计算机不会知道如何“画”出一个字来。我们时常碰到的,在某些电脑上能显示正常,另外一些电脑上则显示乱码的,很有可能就是字库没有能正确安装。

事实上,对于计算机来说,它是意识不到“何为乱码”的,它只是按照既定的编码规则,去把一系列的数字处理成软件预定的内容而已。我们人类看起来无法解读的一堆字符,对于计算机来说和可以解读的正常字符,都是一样的——它们都是一串串的数字。

1.2.3 万国一统Unicode

在整个世界,几乎都接受了ASCII作为英文文字的编码表,一直到现在这个编码规范还在默默的工作。然而中文文字就没有这么幸运了,大陆使用的GB2312编码规范和港台使用的BIG5就是对于中文文字不同的两套编码表。如果我们用BIG5的规则把一些汉字写入文件,比如“你好”,在文件了里记录的是数字“ 42817 42606”,但是按GB2312编码规则读出的时候,却变成另外两个字,因为GB2312编码规则中的“你好”应该是“5040347811”来代表的。如果我们想把日文、韩文,或者别的一些文字混合到同一份文件里,情况将变得更加复杂——想要对一个序列中不同部分的数字,指定不同的编码表的话,你就为每一个代表字符的数字前面,都用另外一个数字来表示应该用哪份编码表。

另外一个更聪明的办法是,把世界上所有的文字,都统一到一份编码表里面来——这就诞生了Unicode。和前文的ASCII编码表相比,Unicode编码表不仅仅为拉丁字母编码,同时也为全世界所有的文字都设计了编码。Unicode至今仍在不断增修,每个新版本都加入更多新的字符。目前最新的版本为第六版,已收入了超过十万个字符(第十万个字符在2005年获采纳)。Unicode发展是由非营利机构“统一码联盟”所负责的。

目前实际应用的Unicode版本叫USC-2,使用16位的编码空间。也就是每个字符占用2个字节。这样理论上一共最多可以表示2的16次方个(即65536)个字符。基本能满足各种语言的需要。下图1-11所示就是用Unicode所显示的多国文字:

图1-11 Unicode文字

使用Unicode编码表来解决各种不同文字的混合显示问题的方法,展示了计算机以数字表达信息的一个通用原理:编码空间设计。如果要表达某种信息,这些信息里面,每个单元的“可能性”全集,决定了编码这个信息单元所需要的数字的长度。——因为英文字母只有几十个,所以使用0~255的数字就可以表示一个英文字母了。而中文字因为有上万个,所以就要用0~65535这么大的数字,才足够表达一个中文字。在计算机中,任何的信息,都遵守这个规律,比如要表达一副黑白图案,每个点只需要0和1两个数字就可以了,因此编码每个点的数字长度只需要用0~1这么小的数字,一连串的0和1就足够描述这个图案。而如果是彩色的图案,每个点所表现的颜色则需要要更长的数字来表达。就需要用一串0~255或者更大的数字来表达。

“用什么数字代表什么意思”的这个工作,就是所谓“编码表”,整个数字世界,就是由这样的各种“编码表”来规定各种各样信息所代表的数字的。

明天,我们接着聊“图片是如何用数字来记录的

感谢大家的阅读,如觉得此文对你有那么一丁点的作用,麻烦动动手指转发或分享至朋友圈。如有不同意见,欢迎后台留言探讨。

原文发布于微信公众号 - 韩大(handa1740168)

原文发表时间:2016-01-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java爬坑系列

易语言 【寻找文本】命令的bug

最近在重写易语言模块的时候,在取子文本操作时老是出错,经常出现一些奇怪的问题,一开始以为是代码问题,可是找半天硬是找不到问题所在。 image.png 于是进...

20811
来自专栏java思维导图

架构师必须掌握的 10 条设计原则

函数是程序员的工具中最重要的抽象形式。它们能更多地被重复使用,你需要编写的代码就越少,代码也因此变得更可靠。较小的函数遵循单一职责原则更有可能被重复使用。

493
来自专栏企鹅号快讯

为什么说Kotlin的可读性比Java好?

作者|小创 编辑|覃云 不久之前,我看了一篇文章,大意是 Kotlin 与 Java 之间的对比,像这种文章,我一般是直接忽略的,但是那天我还是打开了,然后就看...

2415
来自专栏前端知识分享

第66天:闭包的原理和函数传参

在程序语言中,所谓闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型...

794
来自专栏Python攻城狮

爬取拉勾网招聘信息并使用xlwt存入Excel

通过浏览器自带的开发者工具查看是通过Post方式提交的,数据是通过Ajax(异步加载)得到的

674
来自专栏腾讯Bugly的专栏

《广研Android卡顿监控系统》

实现背景 应用的使用流畅度,是衡量用户体验的重要标准之一。Android 由于机型配置和系统的不同,项目复杂App场景丰富,代码多人参与迭代历史较久,代码可能会...

7254
来自专栏测试开发

Android卡顿监控系统

Android 由于机型配置和系统的不同,项目复杂App场景丰富,代码多人参与迭代历史较久等,实际测试时候也会偶尔发现某些业务场景发生卡顿的现象...

3773
来自专栏GreenLeaves

初识javascript

1.简介:Javascript是Netscape(网景)公司与Sun公司(现被甲骨文收购)合作开发的一款是网页具备交互能力的程序设计语言。 2.与之功能相同的语...

1579
来自专栏编程微刊

JavaScript基础

1462
来自专栏PHP技术

编程语言中的闭包

首先,我觉得,一个概念,如果不理解也不影响使用的话,那么,就没必要去理解它、去学习它。闭包就是这样一个概念,你不理解它也能很好的用它。俺这两年写as3程序,是天...

3144

扫码关注云+社区