標籤:

为什么ASCII被摆放成现在这个样子?——我指的是各个ASCII字符的编号顺序

我的疑问来自于这道密码学的编程题目:对正常的英文进行加密,加密算法是明文和key进行异或操作。其中有一个非常关键点事:空格(SPACE, 32),与字母(A-Z, a-z)取异或操作,结果转换为二进制恰好是011*_****。问题是:如果SPACE不是32,那么这个问题就不会有这种解法。这是ASCII制定者当初考虑到的吗?


ASCII需要编码多于64个字符,早期制定标准的时候,有个设想是使用6位来编码字符。添加一些特殊的切换字符,当碰到切换字符时,就切换上下文内容,这样就可以使用6位来编码多于64个字符,更加紧凑。但是这样进行进行传输时,假如切换字符被损坏,就引起后续的一连串字符不可读。最终ASCII选择了7位来编码,8位来传输,因为8位可以表示两个十进制数字,并且字符编码使用了7位,剩下的1位可以作为奇偶验证。

ASCII的字符顺序并非随便排的,有一定规则。计算机是二进制编码,我们将每32个字符作为一个组来看。对计算机来说,32是个整数。

第一个组,也就是编码0-31,全是控制字符。接下来是可显示字符,注意空格也被当成可显示字符了,空格编码为32。最后一个码127,也是控制字符,为删除键。转成二进制,会更清楚地看到,

十进制00为, 000 0000

十进制31为, 001 1111

十进制127为, 111 1111

这样控制字符在两边,显示字符在中间。另外注意到高位的数字为1,并且不是111 1111,就是可显示的。这样可以快速地将字符分类。下图是ASCII码的可显示字符,图片来源于wikipedia,ASCII条目。

在ASCII编码制定前,已经有一些6位大写字符编码了(这些编码方案并没有小写字母),其中有种方案叫DEC SIXBIT。下图是DEC SIXBIT的编码表,

接下来的ASCII编码的两个组,也就是64个字符编码。其实就是DEC SIXBIT的排列顺序,这样ASCII编码就就很容易跟旧方案相互转换。因此ASCII的大写字母,并没有跟小写字母排列在一起。

最后一个组,主要排小写字母。注意到,小写字母跟大写字母,刚好隔开32个位置。这样的话,小写字母跟对应的大写字母二进制中,只会有1位不同。大小写字母的转换也可以很快用位运算来完成。

----------------------

关于ASCII的编码,还有些可以说的。

ASCII编码其中包含了DEC SIXBIT的完整编码。而DEC SIXBIT的排列顺序,有些地方跟老式打字机有点关系。比如数字上面的标点符号的排列,对应了按shift后数字上的标点。键盘布局经过多年演化,到现在还可以找到点影子,比如1上面是!,3上面是#,4上面是$, 5上面是%。跟现在的键盘还是一样的。

ASCII编码整体移动DEC SIXBIT的布局,将字符0的编码放在十进制48的位置,也就对应与二进制的011 0000,字符1就对应于011 0001, 也方便数字的字符跟数值之间的转换。

做游戏时候有时会将数字做成艺术字,美术人员预先做出一些字符的图片。通常会是 +,-./012345679。这个顺序是按照ASCII排列的,包含了加减除符号,还有小数点,数字字符,基本够给程序用了。有时还需要加上×,这时会将,号换成×号。当需要显示×80时,就传进字符串",80"。


推薦閱讀:

如何評價 ScyllaDB?
c++primer和more effective c++的一處矛盾?
如何判斷CTP的行情線程是否阻塞?
Qt 重繪問題?
如何評價基於 C++ 17 的框架 MCF?

TAG:ASCII | C | 密码学 |