A very short article on ASCII characters. Fun fact: ASCII was created by the same guy behind COBOL, and the ESC escape key.

ASCII characters are represented by 7 bits, so that’s 2⁷=128 characters. Some of the characters are the familiar printable characters, and some are the less familiar control characters.

Here are the printable characters, notice they are represented by integers 32 through 126.

> import Data.Char
> map chr [32..126]
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

Here are the control characters as printed by Haskell. (We see escape sequences involving the mnemonics, or abbreviations.)

> map chr $ [0..31] ++ [127]
"\NUL\SOH\STX\ETX\EOT\ENQ\ACK\a\b\t\n\v\f\r\SO\SI\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\EM\SUB\ESC\FS\GS\RS\US\DEL"

Here they are in Emacs Lisp. (We see a textual representation of the keyboard presses.)

> (concat (number-sequence 0 31) '(127))
"^@^A^B^C^D^E^F^G^H \n^K\f^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_^?"

Here they are in Python. (We see the hex code representation.)

>>> ''.join(map(chr, list(range(32)) + [127]))
'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f'

Notice in particular the integers 7 through 13 map to a contiguous block of escape sequences from the C language.

> map chr [7..13]
"\a\b\t\n\v\f\r"

Especially \t and \n are not at all obscure, these are often found in strings representing TAB and newline respectively.

Note another common use of the term “escape sequence” is referring to typing the ESC key and a sequence of characters to control devices in more ways than made available by the 33 control characters. Note that ESC is represented by the integer 27, and the control character ^[. For example, many know that Ctrl+[ is easier to press than ESC when using the vim text editor.

Also, \a is the code for alert, or bell or beep. Another representation of beep is ^G, which happens to be the sequence for cancel (“keyboard-quit”) in Emacs, interestingly enough.

The numbering of characters is of note. Consider the table below.

^@^A^B^C^D^E^F^G^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^&^_
   ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 
 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ 
 ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~^?

This layout corresponds with the representation in hexadecimal, like that found at https://en.wikipedia.org/wiki/ASCII#Code_chart. For example, to convert a control character to its corresponding (and/or uppercase) printable character, we add hexadecimal 40. To convert upper case to lowercase, we add hexadecimal 20.

In binary, the character 0 is represented as 0110000, and increments nicely. Similarly for the alphabet letters. So overall, the layout of the ASCII characters is not random, and has some nice properties.

For further research, here are some links. Enjoy!