- UTF-8 là một phương thức mã hóa độ dài biến thiên vừa biểu diễn được hàng triệu ký tự vừa duy trì tính tương thích ngược với ASCII
- Vùng 7 bit giống hệt ASCII (
U+0000~U+007F) được dùng nguyên vẹn dưới dạng 1 byte, nên tệp ASCII cũng chính là một tệp UTF-8 hợp lệ
- Các ký tự còn lại được biểu diễn bằng chuỗi 2~4 byte, trong đó mẫu bit của byte đầu xác định độ dài còn các byte sau bắt đầu bằng
10 để phân biệt là byte tiếp nối
- Nhờ thiết kế này, UTF-8 có thể xử lý tập ký tự phổ quát mà vẫn tương thích hoàn toàn với các hệ thống ASCII hiện có, nên đã trở thành bảng mã ký tự được dùng rộng rãi nhất
- Các kiểu mã hóa Unicode khác như UTF-16, UTF-32 không cung cấp khả năng tương thích ASCII như vậy
Sự xuất sắc trong thiết kế của UTF-8
- Khi lần đầu tìm hiểu về mã hóa UTF-8, tôi đã rất ấn tượng với cấu trúc tương thích với ASCII hiện có trong khi vẫn bao quát được hàng triệu ký tự của nhiều ngôn ngữ và hệ chữ khác nhau trong một hệ thống duy nhất
- Về cơ bản UTF-8 có thể tận dụng tối đa 32 bit, nhưng ASCII chỉ dùng 7 bit
- Các nguyên tắc thiết kế của UTF-8 như sau
- Mọi tệp mã hóa ASCII đều là tệp UTF-8 hợp lệ
- Mọi tệp UTF-8 chỉ chứa các ký tự ASCII đều là tệp ASCII hợp lệ
- Ý tưởng kết nối một hệ thống cũ chỉ giới hạn ở 128 ký tự với một cơ chế bao quát hàng triệu ký tự thực sự rất đột phá
Khái niệm cơ bản của UTF-8
- UTF-8 là một mã hóa ký tự độ dài biến thiên (variable-width encoding) được thiết kế để biểu diễn mọi ký tự trong bộ ký tự Unicode
- Mỗi ký tự được mã hóa bằng 1~4 byte
- 128 ký tự đầu tiên (
U+0000~U+007F) được lưu bằng một byte duy nhất, nhờ đó đảm bảo tính tương thích ngược với ASCII
- Các ký tự còn lại được mã hóa bằng hai, ba hoặc bốn byte
- Các bit dẫn đầu của byte đầu tiên quyết định tổng số byte cần cho việc mã hóa
| Mẫu 1 byte |
Số byte |
Mẫu toàn bộ chuỗi byte |
| 0xxxxxxx |
1 |
0xxxxxxx (ASCII thông thường) |
| 110xxxxx |
2 |
110xxxxx 10xxxxxx |
| 1110xxxx |
3 |
1110xxxx 10xxxxxx 10xxxxxx |
| 11110xxx |
4 |
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
- Byte thứ 2, 3, 4 trong chuỗi nhiều byte luôn bắt đầu bằng
10, điều này đánh dấu rõ ràng rằng đó là byte tiếp nối
- Các bit còn lại của byte chính và các byte tiếp nối được kết hợp để tạo thành một code point
- Code point là mã định danh duy nhất của một ký tự Unicode, được biểu diễn bằng tiền tố "U+" và số hệ thập lục phân
- Ví dụ: code point của "A" là
U+0041
- Quy trình diễn giải ký tự từ các byte mã hóa UTF-8 như sau
- 1. Đọc một byte; nếu bắt đầu bằng 0 thì coi đó là ký tự một byte (ASCII), dùng 7 bit còn lại để biểu diễn ký tự rồi chuyển sang byte tiếp theo
- 2. Nếu không phải 0 thì
- 110 nghĩa là ký tự 2 byte, đọc thêm 1 byte tiếp theo
- 1110 nghĩa là ký tự 3 byte, đọc thêm 2 byte tiếp theo
- 11110 nghĩa là ký tự 4 byte, đọc thêm 3 byte tiếp theo
- 3. Từ các byte đã xác định, ghép các bit còn lại sau khi bỏ bit đầu để dùng làm giá trị nhị phân của code point
- 4. Tìm code point đó trong bộ ký tự Unicode và hiển thị lên màn hình
- 5. Lặp lại với byte tiếp theo
Ví dụ: ký tự tiếng Hindi "अ"
- Biểu diễn UTF-8:
11100000 10100100 10000101 (3 byte)
- Byte đầu (
11100000) → cho biết đây là ký tự 3 byte
- Kết hợp các bit hữu hiệu của ba byte →
00001001 00000101 = hệ thập lục phân 0x0905
- Code point
U+0905 có nghĩa là ký tự Devanagari "अ"
Ví dụ về tệp
-
1. Hey👋 Buddy
- Gồm tổng cộng 13 byte
- Ký tự ASCII (H, e, y, B, u, d, d, y, dấu cách) → mỗi ký tự 1 byte
- 👋 (U+1F44B) → 4 byte
11110000 10011111 10010001 10001011
- Tệp này là một tệp UTF-8 hợp lệ, nhưng vì chứa ký tự không phải ASCII (emoji) nên không còn tương thích ngược với ASCII
-
2. Hey Buddy
- Tổng cộng 9 byte, tất cả đều nằm trong phạm vi ASCII
- Vì vậy tệp này đồng thời là tệp ASCII hợp lệ và tệp UTF-8 hợp lệ
So sánh với các kiểu mã hóa khác
- Có một vài bảng mã cung cấp khả năng tương thích với ASCII, nhưng không được sử dụng rộng rãi như UTF-8
- GB18030 (tiêu chuẩn của Trung Quốc) cũng hỗ trợ tương thích ASCII nhưng không phổ biến bằng
- Dòng ISO/IEC 8859 là phần mở rộng một byte (tối đa 256 ký tự) nên có giới hạn
- UTF-16/UTF-32 không có tính tương thích ASCII
- 'A' (U+0041): UTF-16 là
00 41, UTF-32 là 00 00 00 41
Bonus: UTF-8 Playground
Chưa có bình luận nào.