本文翻译自 Four Column ASCII,原载于 Hacker News。
发现
前几天在 Hacker News 上发现了一个很棒的内容。用户 soneil 分享了一个四列版本的 ASCII 表,让我恍然大悟。我把它转载到这里,方便更多人发现。
先看看原文的这段话:
我一直觉得 ASCII 表很少以 32 列(或行)的方式展示是个遗憾,因为这样能让很多事情变得一目了然。比如 http://pastebin.com/cdaga5i1 这样一来,为什么 ^[ 等于 escape 就变得显而易见了。还有字母表就是 40h 加上字母的序数位置(小写则是 60h)。或者我们可以通过单个位在大写和小写之间切换。
控制字符
如果你熟悉 ASCII,你会知道表的开头有 32 个字符不代表任何书面符号。退格、换行、转义——诸如此类。这些被称为控制字符(control characters)。
在终端中,你可以通过按住 CTRL 键(control characters,懂了吗?)配合其他键来输入这些控制字符。例如,许多经验丰富的 vim 用户都知道,在终端中按 CTRL+[(脱字符表示法中写作 ^[)等同于按 ESC 键。
但是为什么 escape 键是由 [ 字符触发的?为什么不是其他字符?
这就是 soneil 分享给我们的洞见。
四列 ASCII 表
记住,ASCII 是一个 7 位编码。让我们这样理解:
- 前两位表示字符的组别(2² = 4 个可能的值)
- 剩余五位描述一个字符(2⁵ = 32 个可能的值)
在下面的表格中,四个组别由列表示,行表示具体值:
| 00 | 01 | 10 | 11 | |
|---|---|---|---|---|
| NUL | Spc | @ | ` | 00000 |
| SOH | ! | A | a | 00001 |
| STX | ” | B | b | 00010 |
| ETX | # | C | c | 00011 |
| EOT | $ | D | d | 00100 |
| ENQ | % | E | e | 00101 |
| ACK | & | F | f | 00110 |
| BEL | ’ | G | g | 00111 |
| BS | ( | H | h | 01000 |
| TAB | ) | I | i | 01001 |
| LF | * | J | j | 01010 |
| VT | + | K | k | 01011 |
| FF | , | L | l | 01100 |
| CR | - | M | m | 01101 |
| SO | . | N | n | 01110 |
| SI | / | O | o | 01111 |
| DLE | 0 | P | p | 10000 |
| DC1 | 1 | Q | q | 10001 |
| DC2 | 2 | R | r | 10010 |
| DC3 | 3 | S | s | 10011 |
| DC4 | 4 | T | t | 10100 |
| NAK | 5 | U | u | 10101 |
| SYN | 6 | V | v | 10110 |
| ETB | 7 | W | w | 10111 |
| CAN | 8 | X | x | 11000 |
| EM | 9 | Y | y | 11001 |
| SUB | : | Z | z | 11010 |
| ESC | ; | [ | { | 11011 |
| FS | < | \ | | | 11100 |
| GS | = | ] | } | 11101 |
| RS | > | ^ | ~ | 11110 |
| US | ? | _ | DEL | 11111 |
揭秘
现在在这个表中找一下 ESC。它在第一组,从下往上数第五个。它在第一列,所以它的组别位是 00,行位是 11011。现在看看同一行还有什么?没错,[ 字符就在那里,虽然在不同的列:
10 11011表示[00 11011表示ESC
所以当你输入 CTRL+[ 来获得 ESC 时,你实际上是在请求与字符 11011([)对应的控制字符集中的等价字符。按下 CTRL 只是简单地将你输入字符中除最后 5 位之外的所有位设为零。你可以把它想象成按位与(bitwise AND)操作:
10 11011 ([)
& 00 11111 (CTRL)
= 00 11011 (ESC)
更多发现
这就是为什么:
^J输入一个换行符(newline / LF)^H输入一个退格符(backspace / BS)^I输入一个制表符(tab / TAB)
这也是为什么如果你用 cat -A 查看一个 Windows 文本文件,会看到到处都是 ^M(表示 CR,因为 Windows 的换行符是 CR+LF)。
我的思考
看完这个四列 ASCII 表,我有几点感悟:
-
设计的优雅:ASCII 编码的设计者显然深思熟虑。控制字符、数字、大写字母、小写字母各占一列,这种布局让很多操作变得简单——比如大小写转换只需要翻转一个位(从第 3 列到第 4 列)。
-
为什么是 7 位:现在看来 7 位可能显得”奇怪”(不是 8 的倍数),但这个设计让 128 个字符完美地分成四个 32 字符的组,每组都有其特定用途。
-
CTRL 键的真正含义:我用了这么多年终端,才真正理解 CTRL 键的作用——它实际上是在做一个位掩码操作,把高两位清零。这个设计太精妙了。
-
实用技巧:如果你是 vim 用户,
CTRL+[比ESC更容易按(手指不需要离开主键区)。理解了原理后,你会更愿意使用这个快捷键。
总结
四列 ASCII 表揭示了字符编码背后的逻辑:
- ASCII 的 7 位可以分成 2 位组别 + 5 位字符
- CTRL 键的作用是将高两位清零,只保留低 5 位
- 这就是为什么
CTRL+[=ESC、CTRL+M=CR等等
下次当你看到终端中显示 ^M 或者在 vim 中使用 CTRL+[ 时,你会知道这背后有一套优雅的设计逻辑。