ASCII 码速查表 - ASCII 字符编码大全
很多编码与协议 bug,本质上是"这个字节该是哪个字符"。本表把 ASCII 0~127 按控制字符与可打印字符分开,逐个给出十进制、十六进制、八进制和 HTML 实体,并补充 Latin-1(扩展 ASCII)说明与常见语言的转换写法。调试时把 \n、\r、\t、\0 之类转义和原始字节对上,或在跨语言传输时确认字节与字符是否相符。读完可直接手算十进制与十六进制互转。
典型使用场景
面向需要和「字节」直接打交道的开发者:排查乱码、定位控制字符、还原文件里的十六进制片段,或者在 JS/Python 里做字符与数值的互相转换。本表把三类信息放在一起——控制字符(0-31、127)、可打印区间(32-126)、扩展字符(128-255)——再补上大小写转换的算术规律(相差 32)。最实用的场景是:线上日志里出现看不见的字符导致 JSON 解析失败,或者要确认一个文件到底是 LF 还是 CRLF 行尾。
控制字符 (0-31, 127) 13
0 (0x00)3 (0x03)4 (0x04)7 (0x07)8 (0x08)9 (0x09)10 (0x0A)11 (0x0B)12 (0x0C)13 (0x0D)26 (0x1A)27 (0x1B)127 (0x7F)可打印字符 (32-126) 8
32 (0x20)33-47 (0x21-0x2F)48-57 (0x30-0x39)58-64 (0x3A-0x40)65-90 (0x41-0x5A)91-96 (0x5B-0x60)97-122 (0x61-0x7A)123-126 (0x7B-0x7E)常用控制字符详解 8
LF (10)CR (13)CRLF (13+10)HT (9)ESC (27)DEL (127)NUL (0)ETX (3)扩展 ASCII (128-255) 9
128-159 (0x80-0x9F)160 (0xA0)169 (0xA9)174 (0xAE)176 (0xB0)177 (0xB1)181 (0xB5)215 (0xD7)247 (0xF7)编码转换对照 7
A (65)a (97)0 (48)空格 (32)LF (10)CR (13)~ (126)编程语言转换 8
JS 十进制转字符JS 字符转十进制JS 十进制转十六进制JS 十六进制转十进制Python 十进制转字符Python 字符转十进制Python 十进制转十六进制C 转义符实用速查 8
大小写差值大写转小写小写转大写数字字符转数值可打印范围字母连续性最大 ASCII空格特殊性参数矩阵
| 参数 | 作用 | 示例 |
|---|---|---|
控制字符区 0-31 / 127 | 查询不可见字符的码位与终端键位对应关系,用于排查「看不见的字符」 | 10 (0x0A) :: LF 换行 Line Feed |
可打印范围 32-126 | 判断某个码位是否属于人类可读文本,是过滤二进制数据的第一道判断 | 32-126 共 95 个可打印字符 |
行尾符 LF / CR / CRLF | 区分 Unix、经典 Mac 与 Windows 三种行尾,定位整文件行尾不一致问题 | CRLF (13+10) :: Windows/DOS 行尾符 |
JS / Python 转换函数 | 字符与十进制码位互相转换,用于反查某个符号的真实码位 | String.fromCharCode(65) -> "A" |
大小写差值 32 | 不做库函数、只用算术即可完成大小写互转与字符转数值 | 大写转小写:加 32,或按位或 0x20("A" | 0x20 -> "a") |
易错点与避坑指南
现象把 ESC(27)写进文档或日志后,终端直接吞掉后面的字符或整行乱掉。
原因ESC 是 ANSI 转义序列的起始字节,终端会把它连同后续字节当作控制指令解释。
处置要显示 ESC 本身需转义成可见形式(Ctrl+[ 会打印 ^[),或改用 ESC (27) 这类文字描述。
现象文件在 Windows 记事本里正常,在 Linux 脚本里却是单行。
原因Windows 写出的行尾是 CRLF(13+10),Unix 只认 LF(10),多余的 CR 留在行尾。
处置入库前统一行尾:读入时按 CRLF 拆分,或用 sed -i "s/\r$//" 清掉行尾 CR。
现象删除字符时按 Backspace 只删了一半,末尾多出一个不可见字符。
原因退格键在不同终端可能发 8 (BS) 或 127 (DEL),而两者含义不同。
处置统一按 127 (DEL) 处理「删除光标后字符」,8 (BS) 视作纯粹的退格动作。
现象从十六进制抄来的字符码算出来是负数或乱码。
原因标准 ASCII 只到 127 (0x7F),128-159 (0x80-0x9F) 属于扩展控制字符集,不是可打印文本。
处置只把 32-126 当作可打印区间判断,128 以上按扩展字符或 UTF-8 多字节序列另行处理。
排障路径
1反查一个字符的码位并确认它是否可打印
node -e 'const c=process.argv[1];console.log(c, c.charCodeAt(0), c.charCodeAt(0)>=32&&c.charCodeAt(0)<=126)' A输出码位与是否落在 32-126 可打印区间,false 说明是控制字符。
2把十进制码位转成字符查看它到底是什么
node -e "console.log(JSON.stringify(String.fromCharCode(65)))"用 JSON.stringify 包裹,避免控制字符把终端刷乱。
3检查文件里混入了哪些控制字符
grep -P -n "[\x00-\x08\x0b\x0c\x0e-\x1f]" README.md有输出即说明混入了控制字符,输出的行号可直接定位。
命令示例
Node 里把字符、码位与十六进制互转
node -e "
const ch = 'A';
console.log(ch.charCodeAt(0), (65).toString(16), parseInt('41', 16), String.fromCharCode(65));
console.log('A'.charCodeAt(0) | 0x20, 'a'.charCodeAt(0) & 0xDF);
console.log('7'.charCodeAt(0) - 48);
"第二行的 97 / 65 就是「大小写差 32」的位运算形式:或 0x20 得小写,与 0xDF 得大写。第三行用减 48 把数字字符变成数值。
输出
65 41 65 A 97 65 7
Python 的 ord / chr / hex / oct
python -c "
s = 'A'
print(ord(s), hex(ord(s)), chr(65), oct(65))
print(ord('A') - ord('a'))
"ord 取码位、chr 反向生成字符,hex 与 oct 用于对照表里的十六进制 / 八进制列;最后一行验证大小写差值为 32。
输出
65 0x41 A 0o101 -32
用 od -c 看清制表符与两种行尾
printf 'a\tb\n' | od -c
printf 'a\r\nb\n' | od -c第一段是 LF(码位 10)加 HT(码位 9);第二段显示 Windows 的 CRLF 是 13 加 10 两个字节,行首偏移也从 4 变成 5。
输出
0000000 a \t b \n 0000004 0000000 a \r \n b \n 0000005
扫出一行文本里所有控制字符的码位
node -e "
const line = 'ok\tvalue\r\n';
const bad = [...line].map((c, i) => [i, c.codePointAt(0)]).filter(([, c]) => c < 32 && c !== 0);
console.log(JSON.stringify(bad.map(([i, c]) => i + ':' + c)));
"位置 2 是制表符(9),位置 8、9 是 CRLF 两个字节(13、10)。这个扫描是判断「文件里混进了哪些控制字符」最快的办法。
输出
["2:9","8:13","9:10"]
常见坑与注意事项
- 不要把 ESC(27)直接写进文档、提交信息或日志:终端会吞掉它后面的整段字符,粘贴出去的内容会莫名其妙少一截。
- 跨平台传文本前先统一行尾:LF(10)与 CRLF(13+10)在同一份文件里混用,会让整文件在 Linux 脚本里塌成一行。
- 按 Backspace 删字符时注意 DEL(127):某些程序只删一个字节,末尾可能残留一个看不见的 NUL(0)或不可见控制字符。
- 看到码位是负数或落在 128 以上时,不要继续按 ASCII 解释——那已经是扩展 ASCII 或 UTF-8 的多字节序列,先确定编码。
- NBSP(160)看起来和空格(32)一样,但字符串比较、URL 编码与唯一索引都会因此不相等,做去重前先归一化。
提示
- ASCII 只覆盖 0-127,超出范围需要用 Unicode(如 UTF-8)。
- 换行符在 Linux/macOS 是 LF (10),Windows 是 CRLF (13+10),跨平台传输文本时注意。
- 控制字符不可打印,但常用于协议控制(如 ESC 转义序列、终端颜色)。
- 大小写字母差值为 32 (0x20),位运算转换:大写转小写 OR 0x20,小写转大写 AND 0xDF。
- 128-255 属于扩展 ASCII(Latin-1/ISO-8859-1),在不同编码(GBK/Shift-JIS)下含义不同。
常见问题
为什么 ASCII 只到 127,后面的 128-255 却被反复提到?
因为 0-127 这 128 个码位是 ANSI X3.4 定义的、美国人电报码的最小公共集合,7 位二进制刚好用完,所以叫「7 位 ASCII」。128-255 并不在原始 ASCII 里,它们是后来 IBM PC 把扩展图形字符塞进 8 位高半区形成的扩展 ASCII(俗称 Latin-1 / ISO-8859-1)。同一码位在不同编码里含义不同:160 在 Latin-1 是不间断空格,在某些终端控制表里却是别的控制符,读文件时必须先确定编码,不能只看数字。
33-47、58-64 这些区间为什么全是标点符号?
这是 7 位编码的历史结果。65-90 先被大写字母占掉,97-122 又留给小写字母(大小写各占 26 个码位,必须成对出现才能在只保留大写的旧系统里靠减 32 还原),剩下的码位自然被分配给数字、标点和控制符。结果就是 33-47(! " # $ % & ( ) * + , - . /)与 58-64(: ; < = > ? @)以及 91-96、123-126 全是标点——不是设计者偏好,而是留给可打印符号的「剩余空间」,共 32 个符号。
大小写差 32 这条规律在什么情况下会失效?
只在 ASCII 字母区间内成立。把 0x20 位或到一个非字母上不会得到对应的小写版本——对数字和标点做 OR 0x20 结果不变。规则适用的前提是字符落在 65-90 或 97-122;一旦码位超过 127(扩展 ASCII、UTF-8 多字节序列),按位运算得到的就是无意义的值。对全角字符、多字节字符或非 Latin 脚本必须改用语言自带的转换函数,而不是复用这条算术。
NBSP(160)为什么比普通空格(32)更难发现?
因为 160 在视觉上与 32 完全一致,都不占据可见字形,区别只在「是否允许在此换行」以及字节值本身。它常常从网页复制、Word 导出或 HTML 实体 混入源码,结果是字符串比较不相等、URL 里出现 %C2%A0、数据库唯一索引冲突,而肉眼完全看不出差异。要定位它,只能比较码位:先判断是否等于 32,再看是否落在 160。
把码位反查成字符时,为什么结果可能是一段乱码?
因为单个码位只在它所属的编码里才有意义。用 fromCharCode(65) 能稳定拿到 A,是因为 65 在所有主流编码中都表示 A;而 0xE4 在 UTF-8 里不是一个独立字符,而是后续字节的延续标记,用单字节方式解释就得到乱码。反过来,UTF-8 里一个中文字符占 3 字节,必须按完整序列解码,逐字节查表必然失败。正确做法是先确定文件编码,再按该编码的规则解码整段字节,而不是逐个码位查。
由 巧匠 维护
公开更新于 2026年7月21日,内容持续校对官方文档。