Encodings & Character Sets 101 (P2)
Bài đăng này đã không được cập nhật trong 4 năm
(phần tiếp theo trong loạt bài dịch từ trang kunststube.net/encoding/)
Unicode tham gia vào mớ hỗn độn
Cuối cùng, có một người nọ đã quá mệt mỏi với cái đống hổ lốn ấy và quyết định rèn xích buộc hết lại tạo ra một chuẩn mã hóa để thống nhất tất cả các chuẩn mã hóa. Chuẩn này là Unicode. Về cơ bản, Unicode định nghĩa một bảng siêu to khổng lồ gồm 1.114.112 code point có thể được sử dụng cho vô vàn loại chữ cái và ký hiệu. Số lượng này là thừa sức để mã hóa tất cả các character châu Âu, Trung Đông, Viễn Đông, Nam, Bắc, Tây, trong tiền sử và tương lai mà nhân loại biết tới. Sử dụng Unicode, bạn có thể viết một tài liệu chứa hầu như bất kỳ ngôn ngữ nào, sử dụng bất kỳ ký tự nào bạn có thể nhập vào máy tính. Điều là điều gần như không thể thực hiện được trước khi Unicode xuất hiện. Thậm chí còn có một phần không chính thức cho ngôn ngữ Klingon trong bảng Unicode. Thật vậy, Unicode lớn đến nỗi nó có thể cho phép những khu vực không chính thức sử dụng cho mục đích cá nhân.
Vậy, Unicode sử dụng bao nhiêu bit để mã hóa tất cả các ký tự này? Câu trả lời là KHÔNG MỘT BIT NÀO. Bởi vì Unicode không phải là mà một encoding.
Bạn không phải là người duy nhất cảm thấy xoắn não về việc này. Unicode, về bản chất, định nghĩa một bảng các code point cho các ký tự. Nghe nguy hiểm nhưng thực tế ý chỉ đơn giản là "65 là A, 66 là B và 9.731 là viết tắt của ☃" (thử xem, thật đấy). Việc những code point này thực sự được mã hóa thành bit theo kiểu nào thì lại là một chủ đề khác. Để biểu thị 1.114.112 giá trị khác nhau, hai byte là không đủ. Ba byte thì đủ, nhưng ba byte thường khó xử lý, vì vậy bốn byte sẽ là mức thoải mái tối thiểu. Nhưng, trừ khi bạn thực sự sử dụng tiếng Trung hoặc những ký tự cần nhiều bit để mã hóa, bạn sẽ thường chỉ dùng một phần nhỏ trong bốn byte đó. Nếu chữ "A" luôn được mã hóa thành 00000000 00000000 00000000 01000001, "B" luôn thành 00000000 00000000 00000000 01000010, v.v., thì bất kỳ tài liệu nào cũng sẽ tăng gấp bốn lần kích thước một cách không cần thiết.
Để tối ưu hóa điều này, có một số cách để mã hóa các code point Unicode thành các bit. UTF-32 là một encoding như vậy. UTF-32 mã hóa tất cả các code point Unicode với 32 bit. Tức là bốn byte cho mỗi ký tự. Đây là một cách thức rất đơn giản, nhưng thường gây lãng phí rất nhiều không gian. UTF-16 và UTF-8 là các encoding có độ dài thay đổi. Nếu một ký tự có thể được biểu diễn bằng một byte đơn (vì code point của nó là một số rất nhỏ), UTF-8 sẽ mã hóa nó bằng một byte đơn. Nếu ký tự yêu cầu hai byte, nó sẽ sử dụng hai byte và cứ thế tiếp tục. UTF-8 sử dụng các cơ chế phức tạp để sử dụng các bit cao nhất trong một byte để báo hiệu một ký tự bao gồm bao nhiêu ký tự. Phương pháp này có thể tiết kiệm không gian, nhưng cũng có thể lãng phí không gian nếu các bit tín hiệu này cần được sử dụng thường xuyên. UTF-16 ở giữa, sử dụng ít nhất hai byte, tăng lên tối đa bốn byte khi cần thiết.
Và đấy, ý tưởng chỉ có thế thôi. Unicode là một cái bảng map các ký tự vào với số, và các bảng mã UTF khác nhau xác định cách các số này được mã hóa dưới dạng bit. Nhìn chung, Unicode cũng chỉ là một encoding scheme như bao encoding scheme khác. Không có gì đặc biệt về Unicode, chỉ là nó cố vừa có thể bao quát mọi thứ vừa có thể giữ hiệu quả. Và đó là một điều tốt™.
Code Point
Các ký tự được gọi tên bằng "Unicode code point" của chúng. Các code point Unicode được viết theo hệ thập lục phân (để số không bị dài), với "U+" đi trước (nó chỉ đứng đấy thôi chứ cũng không có ý nghĩa nào khác ngoài "xin chào, đây là một code point Unicode"). Ví dụ, ký tự Ḁ có code point Unicode là U+1E00. Nói cách khác (trong hệ thập phân), đó là ký tự thứ 7680 của bảng Unicode. Tên chính thức của nó là "Chữ cái A Latin viết hoa với vòng tròn ở dưới".
Túm lại cái quần
Tóm tắt tất cả những điều trên: Bất kỳ ký tự nào cũng có thể được mã hóa theo nhiều chuỗi bit khác nhau và bất kỳ chuỗi bit cụ thể nào cũng có thể đại diện cho nhiều ký tự khác nhau, tùy thuộc vào mã hóa nào được sử dụng để đọc hoặc ghi chúng. Lý do đơn giản là vì các bảng mã khác nhau sử dụng số bit khác nhau cho mỗi ký tự, và sử dụng các giá trị khác nhau để thể hiện các ký tự khác nhau.
All rights reserved