2.12 ASCII: Character Encoding as Binary Codes

Convert a character to its ASCII decimal and hexadecimal code, distinguish printable from control characters, and explain how ASCII relates to (and differs from) Unicode.

ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns a unique 7-bit binary code to every letter, digit, punctuation mark, and a set of special control signals, giving digital systems a fixed, universal way to represent human-readable text as bit patterns. Where earlier topics in this module encoded numbers, ASCII encodes symbols — it is the bridge that lets a keyboard keypress, a stored text file, or a transmitted character become nothing more than an ordinary binary number a digital circuit or program can store, compare, and process.

Printable characters and control characters

ASCII's 128 codes (0 through 127, fitting in 7 bits) split into two broad categories. Printable characters are the codes that correspond to a visible symbol when displayed — uppercase and lowercase letters, digits 0-9, punctuation marks, and the space character. Control characters are the lower-numbered codes (and one at the very top of the range, DEL) that do not represent a visible symbol at all, but instead signal an action to a receiving device or program — for example, carriage return, line feed, tab, and backspace are all control characters, historically used to control physical teletype and printer hardware and still used today to structure text files and terminal output.

This split matters practically: code that processes 'text' often needs to explicitly decide how to handle control characters (strip them, interpret them, or reject them), since they are technically part of the ASCII code space but do not behave like ordinary displayable symbols.

The character-to-code mapping

Every ASCII character has a fixed, standardized numeric code, which can be expressed in decimal, binary, or hexadecimal — all three are just different representations of the exact same underlying 7-bit value. The mapping is deliberately structured in useful ways: uppercase letters A-Z occupy a single contiguous block of consecutive codes (65-90), lowercase letters a-z occupy another contiguous block (97-122) offset by exactly 32 from the uppercase block, and the digit characters '0'-'9' occupy their own contiguous block (48-57) — none of which are the same as the numeric values 0-9 themselves, an important and frequent point of confusion.

ASCII vs Unicode

ASCII and Unicode are not interchangeable concepts, and conflating them is a common and consequential mistake. ASCII is a smaller character encoding standard, covering only 128 characters sufficient for basic unaccented English text and control signals. Unicode is a vastly larger standard designed to represent essentially every character used in every written language in the world (well over 100,000 characters as of recent versions), using encoding schemes like UTF-8 that can represent a character in anywhere from 1 to 4 bytes.

The two are related, not equivalent: UTF-8, the dominant Unicode encoding on the modern web, is specifically designed so that the first 128 Unicode code points map to identical single-byte values as ASCII — meaning plain ASCII text is automatically also valid UTF-8 text — but Unicode as a whole vastly exceeds what ASCII alone can represent, and code written assuming 'text is always ASCII' will mishandle any character outside that original 128-symbol set.

ASCII code representation

The character '0' has ASCII code 48, not 0 — this offset must be explicitly handled (e.g., subtracting 48, or '0') when converting a digit character to its numeric value in code. The lowercase and uppercase letter blocks are offset by exactly 32, which is why toggling bit 5 (value 32) of a letter's ASCII code flips it between uppercase and lowercase.

'A' = 65 decimal = 0x41 hexadecimal = 1000001 binary

Key contiguous ranges:
  '0'-'9'  = 48-57   (digit characters -- NOT the same as numeric values 0-9)
  'A'-'Z'  = 65-90   (uppercase letters)
  'a'-'z'  = 97-122  (lowercase letters, offset +32 from uppercase)

Control characters occupy 0-31 and 127 (DEL)

Code Examples

The letter 'A' is assigned decimal code 65 in the ASCII standard. Converting 65 to hexadecimal (using the base-conversion methods from earlier topics) gives 0x41, and converting 0x41 back to decimal (4x16 + 1x1 = 65) confirms the two representations refer to the exact same underlying code.

'A' = 65 decimal = 0x41 hex

'A' = 65 decimal = 0x41 hexadecimal

Check: 0x41 = 4x16 + 1 = 64 + 1 = 65   (matches)

ASCII code space layout

The 128-code ASCII table is organized into contiguous blocks: control characters, punctuation, digits, uppercase letters, more punctuation, and lowercase letters.

0        31 32        47 48   57 58    64 65    90 91  96 97   122 123 127
|control  |  |punct/space| |digits| |punct  | |A-Z    | |punct| |a-z    | |DEL|
|chars    |  |            | |0-9   | |        | |       | |     | |       | |   |
<-------->  <------------> <------> <-------> <-------> <-----> <-------> <---->

Important Rules

ASCII assigns a fixed 7-bit code (0-127) to each character, expressible equivalently in decimal, binary, or hexadecimal.

Printable characters produce a visible symbol; control characters (0-31, and 127/DEL) signal actions rather than displaying a symbol.

The digit characters '0'-'9' have ASCII codes 48-57 — NOT the same as their numeric values 0-9.

ASCII and Unicode are not interchangeable — ASCII is a small 128-character subset; Unicode covers a vastly larger character set, with UTF-8 designed to be backward-compatible with plain ASCII for the first 128 code points.

Where this shows up

Every keyboard input, serial terminal, and plain-text file transfer at some level relies on a character encoding standard descended from or compatible with ASCII; and the ASCII digit-character offset (subtracting 48 to convert a digit character to its numeric value) is one of the most common low-level operations in text-parsing code, from simple calculators to full programming-language lexers.

Assuming the ASCII code of the character '9' is the number 9.

Recognize that the character '9' has ASCII code 57 (in the 48-57 digit block), and subtract 48 (the code of '0') if the actual numeric value 9 is needed.

The digit characters occupy ASCII codes 48-57, not 0-9. Confusing a digit character's ASCII code with the number it visually represents is a very common source of off-by-a-fixed-offset bugs when parsing numeric text.

Using 'ASCII' and 'Unicode' as interchangeable terms, or assuming all text can be safely treated as ASCII.

Treat ASCII as a specific, limited 128-character subset, and use a full Unicode-aware encoding (like UTF-8) whenever text might contain characters outside that basic set (accented letters, non-Latin scripts, emoji, etc.).

ASCII and Unicode are not interchangeable concepts; ASCII is a smaller character encoding standard. Code that assumes 'text is ASCII' will silently mishandle or corrupt any character outside ASCII's original 128-symbol range.

[tricky] Are ASCII and Unicode interchangeable ways of describing character encoding? A. Yes, they are exactly the same standard under two different names B. No — ASCII is a smaller, 128-character encoding standard, while Unicode covers a vastly larger character set (though UTF-8 is designed to be backward-compatible with ASCII for its first 128 codes) C. No, ASCII is newer and has replaced Unicode entirely D. Yes, but only for uppercase letters

B. No — ASCII is a smaller, 128-character encoding standard, while Unicode covers a vastly larger character set (though UTF-8 is designed to be backward-compatible with ASCII for its first 128 codes) — ASCII and Unicode are not interchangeable concepts — ASCII is a smaller character encoding standard covering only 128 characters, sufficient for basic English text and control codes, whereas Unicode is designed to represent virtually every character in every written language.

[interview] Why does the ASCII code for the digit character '9' (57) not equal the number 9? A. Because ASCII encodes the character symbol '9' as a code point, which by design starts the digit block at 48 rather than 0, distinct from the digit's actual numeric meaning B. Because ASCII does not support digit characters at all C. Because '9' is a control character, not a printable one D. Because ASCII codes are always negative for digits

A. Because ASCII encodes the character symbol '9' as a code point, which by design starts the digit block at 48 rather than 0, distinct from the digit's actual numeric meaning — ASCII assigns the character '9' a specific standardized code point (57, i.e., 0x39) as part of its contiguous digit block (48-57), which is unrelated to the digit's numeric value of 9 — code that needs the actual number must explicitly subtract the offset (typically by subtracting the code of '0', 48).

Given that 'A' = 65 decimal, determine the ASCII decimal code for 'a' (lowercase), and separately determine what character has ASCII code 0x30.

'a' = 65 + 32 = 97 decimal (the lowercase block is offset by exactly 32 from uppercase). 0x30 = 48 decimal, which is the ASCII code for the digit character '0'.

Recall the fixed +32 offset between uppercase and lowercase letter blocks, and that the digit block starts at decimal 48 (= 0x30).