Every letter you read on screen is stored as numbers. ASCII was the original mapping; UTF-8 is its modern successor that handles every language on Earth. Understanding the difference explains everything from garbled “mojibake” text to why emoji work.
What Is ASCII?
ASCII (American Standard Code for Information Interchange) maps 128 characters – English letters, digits, punctuation, and control codes – to the numbers 0-127. Each fits in 7 bits, stored as one 8-bit byte.
| Character | Decimal | Binary | Hex |
|---|---|---|---|
| A | 65 | 01000001 | 41 |
| a | 97 | 01100001 | 61 |
| 0 | 48 | 00110000 | 30 |
| space | 32 | 00100000 | 20 |
| ~ | 126 | 01111110 | 7E |
ASCII’s fatal flaw: 128 characters can’t represent é, ñ, 中, or 😀. The world needed more.
What Is UTF-8?
UTF-8 is a variable-length encoding: characters use 1 to 4 bytes depending on their Unicode code point. Its genius is backward compatibility – the first 128 code points (U+0000 to U+007F) encode as identical bytes to ASCII. Every valid ASCII file is automatically valid UTF-8.
| Code Point Range | Bytes | Byte Pattern |
|---|---|---|
| U+0000-U+007F | 1 | 0xxxxxxx |
| U+0080-U+07FF | 2 | 110xxxxx 10xxxxxx |
| U+0800-U+FFFF | 3 | 1110xxxx 10xxxxxx 10xxxxxx |
| U+10000-U+10FFFF | 4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
The leading bits tell you how many bytes the character uses; continuation bytes always start with `10`.
Worked Example: Encoding 'é' (U+00E9)
‘é’ is code point U+00E9 = 11101001 in binary (8 bits). It falls in the 2-byte range:
- Take the bits: `11101001` (pad to 11 bits: `00011101001`)
- Split into 5 + 6: `00011` `101001`
- Fill the template `110xxxxx 10xxxxxx`: `11000011` `10101001`
Result: 0xC3 0xA9 = `11000011 10101001`.
You can verify: paste “é” into a binary converter that shows UTF-8 bytes, or check that 0xC3A9 decodes back to é.
Worked Example: Encoding '€' (U+20AC)
The euro sign is U+20AC. In binary: 0010 0000 1010 1100 (16 bits). It needs 3 bytes:
- Split into 4 + 6 + 6: `0010` `000010` `101100`
- Fill template `1110xxxx 10xxxxxx 10xxxxxx`
- Result: `11100010` `10000010` `10101100` = 0xE2 0x82 0xAC
Three bytes for one character – this is why a file with lots of CJK text is bigger in UTF-8 than in UTF-16.
Worked Example: Encoding '😀' (U+1F600)
Emoji live in the 4-byte range. U+1F600 = 0001 1111 0110 0000 0000 (21 bits):
- Split into 3 + 6 + 6 + 6: `000` `011111` `011000` `000000`
- Fill template `11110xxx 10xxxxxx 10xxxxxx 10xxxxxx`
- Result: `11110000 10011111 10011000 10000000` = 0xF0 0x9F 0x98 0x80
ASCII vs UTF-8: Head to Head
| ASCII | UTF-8 | |
|---|---|---|
| Characters | 128 | 1,112,064 (all of Unicode) |
| Bytes per char | Always 1 | 1-4 (variable) |
| English text size | Same | Same (identical bytes) |
| Non-English | Impossible | Full support |
| Compatibility | – | ASCII files are valid UTF-8 |
For pure English text, UTF-8 and ASCII produce byte-identical output. The difference only appears with characters above U+007F.
What Is Mojibake?
Mojibake (文字化け, “character transformation”) is garbled text like “é” appearing where “é” should be. It happens when UTF-8 bytes are decoded as Latin-1: our é bytes 0xC3 0xA9 get read as two Latin-1 characters à (0xC3) and © (0xA9).
If you ever see Ã, Â, or € appearing as €, you’re looking at an encoding mismatch – the bytes are correct, but the decoder assumed the wrong encoding.
UTF-8 vs UTF-16
UTF-16 uses 2 or 4 bytes per character – more compact for Asian text (3 UTF-8 bytes → 2 UTF-16 bytes for CJK), but wasteful for English and incompatible with ASCII. UTF-8 won because:
- Backward compatible with ASCII (UTF-16 is not)
- No byte-order (endianness) issues
- Better for the web’s English-heavy content
- Self-synchronizing (you can find character boundaries from any byte)
Frequently Asked Questions
Is UTF-8 the same as Unicode?
No. Unicode is the character set (the mapping of numbers to characters like U+00E9 = é). UTF-8 is one *encoding* of Unicode (how those numbers become bytes). UTF-16 and UTF-32 are other encodings of the same Unicode standard.
How can I tell if a file is UTF-8 or ASCII?
If it contains only bytes 0x00-0x7F, it’s both – valid ASCII is valid UTF-8. Bytes 0x80+ with the 110/1110/11110 prefix patterns indicate UTF-8. A BOM (byte order mark, EF BB BF) at the start also signals UTF-8.
Why does 'A' = 65 in both ASCII and UTF-8?
By design. UTF-8 was engineered so the first 128 code points encode as single bytes identical to ASCII. This made migration from ASCII to UTF-8 seamless – trillions of existing files needed zero conversion.
What characters need 4 bytes in UTF-8?
Code points U+10000 and above: emoji (😀), historic scripts, musical symbols, and rare CJK characters. All common modern text fits in 1-3 bytes.
How do I convert text to binary to see the encoding?
Paste any text into a binary converter – multi-byte characters like é will show as 16 bits (2 bytes) instead of 8, revealing the UTF-8 encoding directly.