ASCII#
Standard ASCII is a 7-bit character set defined in 1963 (ANSI X3.4). The first 128 codepoints. Modern Unicode (UTF-8) is fully backward- compatible with ASCII, every ASCII byte represents the same character in UTF-8.
Control Characters (0-31, 127)#
Non-printing control codes. Most are historical; a handful still matter in 2026 (TAB, LF, CR, BEL, ESC, BS, DEL).
Dec / Oct |
Hex |
Char |
C-esc Description |
- |
|---|---|---|---|---|
0 / 000 |
00 |
NUL |
|
- |
1 / 001 |
01 |
SOH |
- |
start of heading |
2 / 002 |
02 |
STX |
- |
start of text |
3 / 003 |
03 |
ETX |
- |
end of text (Ctrl-C interrupt) |
4 / 004 |
04 |
EOT |
- |
end of transmission (Ctrl-D EOF) |
5 / 005 |
05 |
ENQ |
- |
enquiry |
6 / 006 |
06 |
ACK |
- |
acknowledgment |
7 / 007 |
07 |
BEL |
|
- |
8 / 010 |
08 |
BS |
|
- |
9 / 011 |
09 |
HT |
|
- |
10 / 012 |
0A |
LF |
|
- |
11 / 013 |
0B |
VT |
|
- |
12 / 014 |
0C |
FF |
|
- |
13 / 015 |
0D |
CR |
|
- |
14 / 016 |
0E |
SO |
- |
shift out |
15 / 017 |
0F |
SI |
- |
shift in |
16 / 020 |
10 |
DLE |
- |
data link escape |
17 / 021 |
11 |
DC1 |
- |
device control 1 (Ctrl-Q / XON) |
18 / 022 |
12 |
DC2 |
- |
device control 2 |
19 / 023 |
13 |
DC3 |
- |
device control 3 (Ctrl-S / XOFF) |
20 / 024 |
14 |
DC4 |
- |
device control 4 |
21 / 025 |
15 |
NAK |
- |
negative ack |
22 / 026 |
16 |
SYN |
- |
synchronous idle |
23 / 027 |
17 |
ETB |
- |
end transmission block |
24 / 030 |
18 |
CAN |
- |
cancel |
25 / 031 |
19 |
EM |
- |
end of medium |
26 / 032 |
1A |
SUB |
- |
substitute (Ctrl-Z suspend on Unix) |
27 / 033 |
1B |
ESC |
|
- |
28 / 034 |
1C |
FS |
- |
file separator |
29 / 035 |
1D |
GS |
- |
group separator |
30 / 036 |
1E |
RS |
- |
record separator |
31 / 037 |
1F |
US |
- |
unit separator |
127 / 177 |
7F |
DEL |
- |
delete (often the Backspace key) |
CRLF = \r\n (DOS / HTTP / SMTP); LF = \n (Unix); CR = \r
(classic Mac).
Printable Characters (32-126)#
Space and visible characters, the 7-bit ASCII subset every
operator decodes in their head. Knowing the ranges (digits start
at 48, uppercase at 65, lowercase at 97) is what makes byte
dumps in xxd or hexdump -C readable without a lookup.
Dec / Oct |
Hex |
Char |
Notes |
|---|---|---|---|
32 / 040 |
20 |
SPC |
space |
33 / 041 |
21 |
! |
- |
34 / 042 |
22 |
“ |
double quote |
35 / 043 |
23 |
# |
- |
36 / 044 |
24 |
$ |
- |
37 / 045 |
25 |
% |
- |
38 / 046 |
26 |
& |
- |
39 / 047 |
27 |
‘ |
apostrophe / single quote |
40 / 050 |
28 |
( |
- |
41 / 051 |
29 |
) |
- |
42 / 052 |
2A |
- |
|
43 / 053 |
2B |
- |
|
44 / 054 |
2C |
, |
- |
45 / 055 |
2D |
- |
|
46 / 056 |
2E |
. |
- |
47 / 057 |
2F |
/ |
- |
48-57 / 060-71 30-39 0-9 |
- |
- |
digits |
58 / 072 |
3A |
: |
- |
59 / 073 |
3B |
; |
- |
60 / 074 |
3C |
< |
- |
61 / 075 |
3D |
= |
- |
62 / 076 |
3E |
> |
- |
63 / 077 |
3F |
? |
- |
64 / 100 |
40 |
@ |
- |
65-90 / 101-132 41-5A A-Z |
- |
- |
uppercase letters |
91 / 133 |
5B |
[ |
- |
92 / 134 |
5C |
\ |
backslash |
93 / 135 |
5D |
] |
- |
94 / 136 |
5E |
^ |
- |
95 / 137 |
5F |
_ |
- |
96 / 140 97-122 / 141-172 61-7A a-z lowercase letters |
60 |
` |
backtick |
123 / 173 |
7B |
{ |
- |
124 / 174 |
7C |
- |
|
125 / 175 |
7D |
} |
- |
126 / 176 |
7E |
~ |
- |
Letter / Digit Codepoint Tricks#
Useful relationships an experienced operator just remembers.
Most are about the regular spacing of the alphabet ranges,
once you know that case differs by a single bit (0x20), you
can convert between cases with bitops without reaching for a
library function.
Digits
'0'to'9'are 48 to 57 (0x30to0x39).Uppercase
'A'to'Z'are 65 to 90 (0x41to0x5A).Lowercase
'a'to'z'are 97 to 122 (0x61to0x7A).The difference between an uppercase and lowercase letter is exactly
0x20(32).'A' | 0x20 == 'a';'a' & ~0x20 == 'A'.Digit-to-int:
'0' + ngives the character;c - '0'gives the value.'A' + (n % 26)cycles through the alphabet.
Escape Sequences#
Common escape sequences and what they map to. Most of these are
identical across Bash, C, Python, and JavaScript string literals
– \n is always newline, \t is always tab, \xHH is
always a byte by hex.
Sequence |
Code (dec) |
Description |
|---|---|---|
|
0 |
null |
|
7 |
bell |
|
8 |
backspace |
|
9 |
horizontal tab |
|
10 |
line feed (newline) |
|
11 |
vertical tab |
|
12 |
form feed |
|
13 |
carriage return |
|
27 |
escape (GNU extension; |
|
92 |
backslash |
|
39 |
single quote |
|
34 |
double quote |
|
hex |
any byte by hex ( |
|
octal |
any byte by octal ( |
|
Unicode |
BMP code point ( |
|
- |
full code point ( |
Terminal ESC Sequences#
Almost all “ANSI escape codes” begin with ESC (27, \033 ,
\x1b, \e) followed by [ (a “Control Sequence Introducer”).
The most common ones:
Sequence |
Effect |
|---|---|
|
reset all attributes |
|
bold |
|
dim |
|
italic |
|
underline |
|
reverse |
|
foreground (black, red, green, yellow, blue, magenta, cyan, white) |
|
background (same colors) |
|
bright foreground |
|
truecolor foreground |
|
clear screen |
|
cursor home |
|
cursor position (row N, column M) |
|
hide / show cursor |
Example:
$ printf '\e[31;1mError:\e[0m something failed\n'
ASCII vs. Unicode#
The encoding context every operator should keep straight. ASCII is the 7-bit common ancestor; Latin-1 and Windows-1252 are 8-bit extensions still alive in legacy data; UTF-8 is the modern universal default and a strict superset of ASCII at the byte level.
ASCII is 7-bit (codepoints 0-127). Every ASCII byte is the same byte in UTF-8.
Latin-1 / ISO-8859-1 extended ASCII to 8 bits with European characters.
Windows-1252 extended Latin-1 with curly quotes, em-dash, etc. Often misidentified as Latin-1.
UTF-8 is the universal encoding in 2026; ASCII is a strict subset.
Code page 437 is the original IBM PC character set with the classic line-drawing characters; appears in BIOS / DOS / serial- console contexts.
For modern programming, treat strings as Unicode (UTF-8) and use ASCII only when you mean specifically the 0-127 range.
Looking It Up#
The on-machine lookups when you need a codepoint in the moment.
man ascii is everywhere; ord() and chr() are the
Python equivalents; xxd shows you the byte values of any
file or string.
In a shell:
$ man ascii
$ ascii 65
$ echo -n A | xxd
In Python:
ord('A') # 65
chr(65) # 'A'
'A'.encode('utf-8') # b'A'
bytes([65, 66, 67]) # b'ABC'
In JavaScript:
'A'.charCodeAt(0) // 65
String.fromCharCode(65) // 'A'