Bảng mã ký tự là bảng quy ước mỗi chữ, mỗi dấu câu ứng với một con số, để máy tính lưu và truyền chữ dưới dạng số. ASCII (Mỹ, 1963) chỉ có 128 vị trí, đủ cho chữ Latinh không dấu; các nước phải tự chế bảng mã 8 bit riêng để thêm chữ của mình — tiếng Việt từng có cả chục bảng mã như vậy. Unicode ra đời đầu thập niên 1990 gom chữ viết của mọi ngôn ngữ vào một bảng duy nhất, và là lý do hôm nay ta gõ tiếng Việt gửi đi đâu cũng hiện đúng.
Máy tính không biết chữ, chỉ biết số
Bên trong máy tính, mọi thứ là chuỗi bit 0 và 1. Muốn lưu chữ "A", phải có quy ước: chữ A là số 65. Muốn người gửi và người nhận thấy cùng một chữ, hai bên phải dùng chung quy ước đó. Bảng quy ước ấy gọi là bảng mã ký tự (character encoding, hay character set).
Nếu người gửi dùng bảng mã này mà người nhận đọc bằng bảng mã khác, con số vẫn đúng nhưng chữ hiện ra sai — đó là gốc rễ của hiện tượng chữ Việt biến thành ký tự lạ, được giải thích riêng trong một bài của mục này.
ASCII: 128 ký tự cho tiếng Anh
ASCII (American Standard Code for Information Interchange) được ban hành ở Mỹ năm 1963 và sửa đổi năm 1967. Nó dùng 7 bit, tức 128 vị trí (0–127):
- 33 mã điều khiển (xuống dòng, tab, chuông…) — phần lớn ở vị trí 0–31, cộng thêm mã 127.
- Dấu cách, chữ số 0–9, dấu câu và ký hiệu như @, #, %.
- 26 chữ hoa A–Z (65–90) và 26 chữ thường a–z (97–122).
Không có chữ nào có dấu. Với tiếng Việt, ASCII chỉ viết được kiểu không dấu — "Viet Nam". Đến nay, 128 ký tự ASCII vẫn là phần lõi của gần như mọi bảng mã, kể cả Unicode.
Thời 8 bit: mỗi nước một bảng, mỗi hãng một kiểu
Máy tính lưu dữ liệu theo byte 8 bit, tức có 256 vị trí. ASCII chỉ dùng nửa dưới, nửa trên (128–255) để trống. Mỗi nước, mỗi hãng lấp nửa trên theo cách riêng:
- Châu Âu có bộ tiêu chuẩn ISO 8859 (bắt đầu từ cuối thập niên 1980), ví dụ ISO 8859-1 cho Tây Âu.
- Microsoft có các "code page" như Windows-1252 cho Tây Âu và Windows-1258 cho tiếng Việt.
- Nhật, Trung, Hàn có quá nhiều chữ, phải dùng bảng mã nhiều byte riêng.
Tiếng Việt gặp khó đặc biệt: có 134 chữ cái có dấu (67 thường, 67 hoa), trong khi nửa trên của một byte chỉ có 128 chỗ. Vì vậy các bảng mã tiếng Việt 8 bit đều phải "lách": bỏ chữ hoa có dấu sang phông riêng, ghép chữ từ hai byte, hoặc chiếm cả vị trí của mã điều khiển. Mục này có bài riêng về TCVN3 và về VNI, VISCII, VPS.
Unicode: một bảng cho mọi chữ viết
Hiệp hội Unicode (Unicode Consortium) được thành lập năm 1991 tại California, cùng năm công bố Unicode 1.0. Song song, tổ chức ISO có tiêu chuẩn ISO/IEC 10646; hai bên thống nhất để hai chuẩn dùng chung một bảng ký tự. Ý tưởng cốt lõi:
- Mỗi ký tự của mọi chữ viết trên thế giới có một số hiệu duy nhất, gọi là code point, viết dạng U+ kèm số hệ mười sáu. Ví dụ chữ "A" là U+0041, chữ "ệ" là U+1EC7.
- Không gian mã có hơn một triệu vị trí (từ U+0000 đến U+10FFFF), chia thành 17 "mặt phẳng".
- Bảng được mở rộng qua từng phiên bản: thêm chữ cổ, ký hiệu toán học, biểu tượng cảm xúc…
Tiếng Việt có đủ 134 chữ dựng sẵn trong Unicode, nằm rải ở mấy vùng khác nhau. Việt Nam đưa Unicode vào tiêu chuẩn quốc gia TCVN 6909:2001 — xem bài riêng về chuẩn này.
UTF-8, UTF-16: số hiệu và cách lưu là hai chuyện
Unicode cho mỗi chữ một số hiệu. Còn ghi số đó ra byte thế nào lại là chuyện của các dạng mã hoá:
| Dạng | Số byte mỗi ký tự | Hay dùng ở đâu |
|---|---|---|
| UTF-8 | 1 đến 4 byte; ASCII giữ nguyên 1 byte | Trang web, email, tệp văn bản, Linux, macOS — phổ biến nhất hiện nay |
| UTF-16 | 2 hoặc 4 byte | Bên trong Windows, Java, JavaScript |
| UTF-32 | Luôn 4 byte | Xử lý nội bộ, ít dùng để lưu |
UTF-8 được Ken Thompson và Rob Pike thiết kế năm 1992. Ưu điểm lớn: văn bản tiếng Anh thuần ASCII không đổi một byte nào, nên tương thích ngược với phần mềm cũ.
Một chữ Việt đi qua các tầng như thế nào
Lấy chữ "Việt" làm ví dụ. Kết quả dưới đây có thể tự kiểm bằng bất kỳ công cụ tra Unicode nào.
| Chữ | Code point | Byte UTF-8 | Byte UTF-16 |
|---|---|---|---|
| V | U+0056 | 56 | 00 56 |
| i | U+0069 | 69 | 00 69 |
| ệ | U+1EC7 | E1 BB 87 | 1E C7 |
| t | U+0074 | 74 | 00 74 |
Chữ "Việt" có 4 ký tự nhưng chiếm 6 byte ở UTF-8: chữ ệ một mình tốn 3 byte. Đây là lý do một số hệ thống giới hạn độ dài theo byte (như tin nhắn SMS, cột cơ sở dữ liệu cũ) cho phép gõ ít chữ tiếng Việt có dấu hơn chữ không dấu.
Bảng mốc: từ ASCII đến Unicode ở Việt Nam
| Năm | Mốc |
|---|---|
| 1963 | ASCII được ban hành ở Mỹ (sửa đổi 1967) |
| cuối thập niên 1980 | Bộ tiêu chuẩn ISO 8859 cho các ngôn ngữ châu Âu |
| 1991 | Thành lập Hiệp hội Unicode, công bố Unicode 1.0 |
| 1992 | Thiết kế UTF-8 |
| 1993 | Việt Nam ban hành TCVN 5712:1993 (bảng mã 8 bit, quen gọi TCVN3); cùng năm RFC 1456 mô tả VISCII và VIQR |
| 2001 | Ban hành TCVN 6909:2001 — bộ mã tiếng Việt theo Unicode |
| 2002 | Quyết định 72/2002/QĐ-TTg yêu cầu cơ quan nhà nước dùng TCVN 6909:2001 trong văn bản điện tử |
Bài tập: tự tra mã của chữ mình gõ
- Trong Microsoft Word trên Windows, gõ một chữ, ví dụ "ơ", đặt con trỏ ngay sau nó rồi nhấn Alt + X. Chữ sẽ biến thành mã hệ mười sáu của nó, ở đây là 01A1. Nhấn Alt + X lần nữa để đổi ngược lại.
- Thử với các chữ "ă", "đ", "ư", "ạ", "ỹ". Ghi kết quả vào bảng; bạn sẽ thấy chúng nằm ở các vùng khác nhau (0103, 0111, 01B0, 1EA1, 1EF9).
- Gõ ngược: gõ "1EC7" rồi Alt + X, sẽ ra "ệ". Đây cũng là cách chèn một ký tự khi không nhớ cách gõ.
Góc nhìn hôm nay
Ngày nay đa số người dùng không còn phải nghĩ về bảng mã: máy mới, phần mềm mới đều mặc định Unicode, phần lớn là UTF-8. Nhưng hiểu chuyện "chữ là số" giúp xử lý những lúc trục trặc — tệp cũ mở ra toàn ký tự lạ, tệp CSV xuất từ phần mềm kế toán hỏng dấu, tên tệp có dấu bị méo khi chuyển máy. Trang unicode.org có bảng tra mọi ký tự theo vùng; với tiếng Việt, hãy xem các bảng "Latin-1 Supplement", "Latin Extended-A", "Latin Extended-B" và "Latin Extended Additional".
Câu hỏi thường gặp
Bảng mã ký tự là gì?
Bảng mã ký tự là quy ước gán mỗi chữ, chữ số, dấu câu với một con số để máy tính lưu và truyền văn bản. Hai bên dùng chung bảng mã thì chữ hiện đúng, khác bảng mã thì chữ bị sai lệch.
ASCII và Unicode khác nhau thế nào?
ASCII chỉ có 128 ký tự, đủ cho chữ Latinh không dấu. Unicode có không gian hơn một triệu vị trí, chứa chữ viết của gần như mọi ngôn ngữ, trong đó có đủ 134 chữ cái có dấu của tiếng Việt. 128 ký tự đầu của Unicode trùng với ASCII.
UTF-8 có phải là Unicode không?
UTF-8 là một cách ghi các số hiệu Unicode ra byte. Unicode quy định mỗi chữ là số mấy, còn UTF-8, UTF-16 quy định số đó được lưu thành bao nhiêu byte và theo thứ tự nào.
Tiếng Việt có bao nhiêu chữ cái có dấu?
Tiếng Việt có 67 chữ thường có dấu (gồm đ và các nguyên âm kèm dấu mũ, móc, trăng và dấu thanh) và 67 chữ hoa tương ứng, tổng 134. Unicode có đủ cả 134 chữ ở dạng dựng sẵn.
Vì sao chữ có dấu tốn nhiều byte hơn?
Trong UTF-8, chữ ASCII chỉ tốn 1 byte, còn chữ có dấu tiếng Việt tốn 2 hoặc 3 byte. Ví dụ "ệ" tốn 3 byte, nên chữ "Việt" có 4 ký tự nhưng chiếm 6 byte.