← HTML 表单:从控件到提交与校验 / Ctrl+H 为什么是退格 待审核 1 / 24
ASCII · 0–31

Ctrl+H 为什么是退格

npm 包 charcodes 里的 backSpace = 8 并非随意指定——它来自 1963 年的 ASCII 表。ASCII 一共 128 个位置,前 32 个 (0–31) 加上最后一个 (127) 全是看不见的控制字符:它们不是「字」,而是发给电传打字机 teletype指令——退一格、走一行纸、摇回行首、响个铃。更关键的是,Ctrl 键的本职工作就是把字母「变成」控制字符:按住 Ctrl 等于把字母编码的高两位清零,所以 Ctrl+H = 72 & 0x1F = 8 = 退格。这一页把整张表和这条算式摊开看。

1 · 整张 ASCII 表——点任意格子看它的身份

蓝色 = 控制字符(0–31 与 127),白色 = 可打印字符 (32–126),橙色 = 空格。注意控制区和字母区的纵向对应:每个控制字符正上方差 64 的位置,就是它的 Ctrl 字母。

为什么 DEL 偏偏是 127,不与其他字符同处 0–31? 因为纸带。早年程序打在穿孔纸带上,打错了没法擦——唯一的补救是把那一列七个孔全部打穿,约定「全是孔 = 作废」。七位全 1 正是 1111111 = 127。DEL 是物理介质留在编码表里的活化石。

2 · Ctrl 的本职:清零高两位,字母变指令

电传打字机时代没有「快捷键」概念——Ctrl 是个修饰电路:按住它,键发出的编码会被按位与 0x1F(保留低 5 位)。选一个字母,看这步位运算怎么把它变成控制字符:

这就是终端快捷键的「词源」: Ctrl+I = Tab、Ctrl+J = 换行、Ctrl+M = 回车、Ctrl+[ = Esc(所以 Vim 里 Ctrl+[ 能退出插入模式)、Ctrl+C = ETX(被 Unix 拿去当中断信号)。控制字符的「caret notation」写法 ^H ^[ 也由此而来——^X 就读作 Ctrl+X。在终端里连按 Backspace 有时会看到 ^H^H^H,正是它的本名。

3 · 键盘上活下来的控制字符

128 个里今天还印在键帽上 / 天天路过你字符串的,其实就这几个:

字符 code caret 转义 键盘 今天在哪
NUL 空字符 0 ^@ \0 C 字符串结尾 · 纸带上的空白段
BEL 响铃 7 ^G \a 终端里 echo 它会「叮」一声
BS 退格 8 ^H \b Backspace 键盘 Backspace · charcodes 的 backSpace
HT 水平制表 9 ^I \t Tab 键盘 Tab · 缩进之争的主角
LF 换行 10 ^J \n (Enter 的一半) Unix 换行符
CR 回车 13 ^M \r Enter Windows 换行 = CR+LF · HTTP 行尾
ESC 转义 27 ^[ \x1B Esc 键盘 Esc · ANSI 彩色转义序列的开头
DEL 删除 127 ^? (Mac 上 Delete 发的是它) 纸带「打满孔作废」的活化石

CR 和 LF 为什么是两个字符? 打字机上「换行」真的是两个机械动作:CR(carriage return)把滚筒摇回行首,LF(line feed)把纸卷上一行。电传机照搬了这套,于是文本世界从此分裂:Unix 只留 \n、老 Mac 只留 \r、Windows 两个都要 \r\n——git 的 autocrlf、HTTP 头的 CRLF 行尾,根都在打字机的两个零件上。