Mã Hóa Ký Tự UTF-8, UTF-16 Và UTF-32: Bản Chất Byte & Tránh Lỗi Font
Hiểu rõ cơ chế biến đổi code point Unicode thành byte trong UTF-8, xử lý Byte Order Mark (BOM) và khắc phục triệt để lỗi hiển thị font.
Text encoding bugs—mojibake characters like é instead of é—happen when software misinterprets the byte sequences representing Unicode code points. Understanding how UTF-8, UTF-16, and UTF-32 encode characters is essential for building resilient file processing pipelines.
The Unicode Model: Code Points vs Bytes
Unicode maps abstract characters to numeric code points (e.g. U+0041 for 'A', U+1F600 for '😀'). The transformation format (UTF) dictates how those numbers are serialized into binary bytes.
| Encoding | Bytes per Character | Self-Synchronizing? | Web Adoption |
|---|---|---|---|
| UTF-8 | 1 to 4 bytes (Variable) | Yes | 98.2% of all websites |
| UTF-16 | 2 or 4 bytes (Variable) | No (Requires BOM/Endianness) | Windows internal / JVM / JS engine |
| UTF-32 | Exactly 4 bytes (Fixed) | Yes | Rare (high memory overhead) |
Download our 1MB UTF-8 text file to test character decoding and multibyte parsing.
Tải File Mẫu 1MB TXT →How UTF-8 Variable Length Works
- ASCII characters (0-127): Encoded in 1 byte (
0xxxxxxx), maintaining 100% backwards compatibility with legacy ASCII. - Latin, Greek, Cyrillic (128-2047): Encoded in 2 bytes.
- Asian scripts, CJK (2048-65535): Encoded in 3 bytes.
- Emojis & rare symbols (65536+): Encoded in 4 bytes.
// Decoding bytes safely in Node.js
import { TextDecoder } from 'util';
export function decodeTextSafely(buffer: Buffer): string {
// fatal: true throws an exception instead of inserting replacement characters
const decoder = new TextDecoder('utf-8', { fatal: true });
return decoder.decode(buffer);
}
The Byte Order Mark (BOM)
UTF-8 does not require a Byte Order Mark because bytes are ordered identically on big-endian and little-endian machines. However, some Windows software (Notepad, Excel) prepends 0xEF 0xBB 0xBF. Always strip leading BOM bytes when parsing text files in Node.js.
Nguyễn Đại Long
Tác GiảBackend Lead • Chuyên gia Kiến trúc Hệ thống Phân tán & Lưu trữ Đám mây
Hơn 4 năm kinh nghiệm thiết kế các hệ thống xử lý tệp tải lên thông lượng lớn, tối ưu hóa cơ sở dữ liệu và hạ tầng phân tán Cloudflare R2 / AWS S3. Người sáng lập FileDummy và Mạng lưới Hệ sinh thái NDL.
Bài viết này có hữu ích không?
Bấm Thích để ủng hộ tác giả và giúp bài viết lan tỏa tới cộng đồng lập trình viên.
Thảo Luận Kỹ Thuật & Đóng Góp Ý Kiến (0)
Chia sẻ kết quả benchmark, phản hồi các trường hợp biên hoặc đặt câu hỏi chuyên môn.
Chưa có bình luận nào. Hãy là lập trình viên đầu tiên bắt đầu cuộc thảo luận!
Câu Hỏi Thường Gặp (FAQ)
Why is UTF-8 dominant on the web?▾
UTF-8 is backward-compatible with ASCII, self-synchronizing (character boundaries are detectable without reading from the start), has no byte order ambiguity, and is space-efficient for ASCII-heavy text. HTTP, HTML5, JSON, and XML all default to UTF-8.
What is a BOM (Byte Order Mark) and do I need it?▾
A BOM is a special Unicode character (U+FEFF) that indicates byte order for UTF-16/UTF-32, or identifies UTF-8. UTF-8 BOM (EF BB BF) is optional and often causes problems with parsers. Modern tooling recommends UTF-8 without BOM.
When should I use UTF-16 instead of UTF-8?▾
UTF-16 is used internally by Windows APIs, Java, JavaScript engines, and .NET — they store strings as UTF-16 in memory. For file storage and network transmission, prefer UTF-8. Use UTF-16 only when required by specific APIs.