Tại sao chúng ta cần Unicode?
Trong những ngày đầu (không quá), tất cả những gì tồn tại là ASCII. Điều này không sao, vì tất cả những gì cần thiết là một vài ký tự điều khiển, dấu câu, số và chữ cái giống như trong câu này. Thật không may, thế giới kỳ lạ của truyền thông xã hội và truyền thông xã hội ngày nay không lường trước được và không quá bất thường khi thấy tiếng Anh, tiếng Anh,, עִבְ עִבְעִבְ trình duyệt).
Nhưng để tranh luận, giả sử Joe Average là nhà phát triển phần mềm. Anh ấy khẳng định rằng anh ấy sẽ chỉ cần tiếng Anh, và như vậy chỉ muốn sử dụng ASCII. Điều này có thể tốt cho người dùng Joe , nhưng điều này không tốt cho Joe nhà phát triển phần mềm . Khoảng một nửa thế giới sử dụng các ký tự không phải là tiếng Latinh và sử dụng ASCII được cho là không phù hợp với những người này, và trên hết, anh ta đang đóng cửa phần mềm của mình cho một nền kinh tế lớn và đang phát triển.
Do đó, một bộ ký tự bao gồm tất cả các ngôn ngữ là cần thiết. Do đó, Unicode. Nó gán cho mỗi ký tự một số duy nhất gọi là điểm mã . Một lợi thế của Unicode so với các bộ có thể khác là 256 điểm mã đầu tiên giống hệt với ISO-8859-1 , và do đó cũng là ASCII. Ngoài ra, phần lớn các ký tự thường được sử dụng chỉ có thể biểu thị bằng hai byte, trong một vùng được gọi là Mặt phẳng đa ngôn ngữ cơ bản (BMP) . Bây giờ cần mã hóa ký tự để truy cập bộ ký tự này và như câu hỏi yêu cầu, tôi sẽ tập trung vào UTF-8 và UTF-16.
Cân nhắc bộ nhớ
Vì vậy, có bao nhiêu byte cung cấp quyền truy cập vào các ký tự trong các bảng mã này?
- UTF-8:
- 1 byte: ASCII tiêu chuẩn
- 2 byte: tiếng Ả Rập, tiếng Do Thái, hầu hết các chữ viết châu Âu (đáng chú ý nhất là tiếng Gruzia )
- 3 byte: BMP
- 4 byte: Tất cả các ký tự Unicode
- UTF-16:
- 2 byte: BMP
- 4 byte: Tất cả các ký tự Unicode
Điều đáng nói bây giờ là các nhân vật không có trong BMP bao gồm các chữ viết cổ, ký hiệu toán học, ký hiệu âm nhạc và các ký tự Trung Quốc / Nhật Bản / Hàn Quốc (CJK) hiếm hơn .
Nếu bạn sẽ làm việc chủ yếu với các ký tự ASCII, thì UTF-8 chắc chắn sẽ hiệu quả hơn về bộ nhớ. Tuy nhiên, nếu bạn đang làm việc chủ yếu với các tập lệnh phi châu Âu, sử dụng UTF-8 có thể hiệu quả bộ nhớ thấp hơn tới 1,5 lần so với UTF-16. Khi xử lý một lượng lớn văn bản, chẳng hạn như các trang web lớn hoặc các tài liệu từ dài, điều này có thể ảnh hưởng đến hiệu suất.
Mã hóa cơ bản
Lưu ý: Nếu bạn biết UTF-8 và UTF-16 được mã hóa như thế nào, hãy bỏ qua phần tiếp theo cho các ứng dụng thực tế.
- UTF-8: Đối với các ký tự ASCII (0-127) tiêu chuẩn, mã UTF-8 giống hệt nhau. Điều này làm cho UTF-8 trở nên lý tưởng nếu cần có khả năng tương thích ngược với văn bản ASCII hiện có. Các ký tự khác yêu cầu bất cứ nơi nào từ 2-4 byte. Điều này được thực hiện bằng cách dự trữ một số bit trong mỗi byte này để chỉ ra rằng nó là một phần của ký tự nhiều byte. Cụ thể, bit đầu tiên của mỗi byte là
1
để tránh xung đột với các ký tự ASCII.
- UTF-16: Đối với các ký tự BMP hợp lệ, đại diện UTF-16 chỉ đơn giản là điểm mã của nó. Tuy nhiên, đối với các ký tự không phải BMP, UTF-16 giới thiệu các cặp thay thế . Trong trường hợp này, sự kết hợp của hai phần ánh xạ hai byte thành một ký tự không phải BMP. Các phần hai byte này đến từ phạm vi số BMP, nhưng được đảm bảo theo tiêu chuẩn Unicode là không hợp lệ dưới dạng ký tự BMP. Ngoài ra, vì UTF-16 có hai byte là đơn vị cơ bản của nó, nên nó bị ảnh hưởng bởi tuổi thọ . Để bù lại, một dấu thứ tự byte dành riêng có thể được đặt ở đầu luồng dữ liệu cho biết độ bền. Do đó, nếu bạn đang đọc đầu vào UTF-16 và không có chỉ định về tuổi thọ, bạn phải kiểm tra điều này.
Có thể thấy, UTF-8 và UTF-16 không tương thích với nhau. Vì vậy, nếu bạn đang thực hiện I / O, hãy chắc chắn rằng bạn biết bạn đang sử dụng mã hóa nào! Để biết thêm chi tiết về các bảng mã này, vui lòng xem Câu hỏi thường gặp về UTF .
Cân nhắc lập trình thực tế
Các kiểu dữ liệu ký tự và chuỗi: Chúng được mã hóa bằng ngôn ngữ lập trình như thế nào? Nếu chúng là byte thô, phút mà bạn cố gắng xuất các ký tự không phải ASCII, bạn có thể gặp phải một số vấn đề. Ngoài ra, ngay cả khi loại ký tự dựa trên UTF, điều đó không có nghĩa là các chuỗi là UTF phù hợp. Họ có thể cho phép các chuỗi byte là bất hợp pháp. Nói chung, bạn sẽ phải sử dụng thư viện hỗ trợ UTF, chẳng hạn như ICU cho C, C ++ và Java. Trong mọi trường hợp, nếu bạn muốn nhập / xuất một cái gì đó ngoài mã hóa mặc định, bạn sẽ phải chuyển đổi nó trước.
Mã hóa được đề xuất / mặc định / chiếm ưu thế: Khi được lựa chọn sử dụng UTF nào, tốt nhất là tuân theo các tiêu chuẩn được đề xuất cho môi trường bạn đang làm việc. Ví dụ: UTF-8 chiếm ưu thế trên web và kể từ HTML5, nó đã được mã hóa đề nghị . Ngược lại, cả môi trường .NET và Java đều được thiết lập trên loại ký tự UTF-16. Một cách khó hiểu (và không chính xác), các tham chiếu thường được thực hiện cho "mã hóa Unicode", thường đề cập đến mã hóa UTF chi phối trong một môi trường nhất định.
Hỗ trợ thư viện: Các thư viện bạn đang sử dụng hỗ trợ một số loại mã hóa. Cái nào? Họ có hỗ trợ các trường hợp góc? Vì sự cần thiết là mẹ của sáng chế, các thư viện UTF-8 thường sẽ hỗ trợ đúng các ký tự 4 byte, vì các ký tự 1, 2 và thậm chí 3 byte có thể xảy ra thường xuyên. Tuy nhiên, không phải tất cả các thư viện UTF-16 có mục đích đều hỗ trợ các cặp thay thế đúng vì chúng rất hiếm khi xảy ra.
Đếm các ký tự: Có tồn tại kết hợp các ký tự trong Unicode. Ví dụ: điểm mã U + 006E (n) và U + 0303 (dấu ngã kết hợp) tạo thành ñ, nhưng điểm mã U + 00F1 tạo thành ñ. Chúng trông giống hệt nhau, nhưng một thuật toán đếm đơn giản sẽ trả về 2 cho ví dụ đầu tiên, 1 cho cái sau. Điều này không hẳn là sai, nhưng cũng có thể không phải là kết quả mong muốn.
So sánh về sự bình đẳng: A, Ny và Α trông giống nhau, nhưng chúng lần lượt là tiếng Latin, Cyrillic và Hy Lạp. Bạn cũng có những trường hợp như C và, một là chữ cái, cái còn lại là chữ số La Mã. Ngoài ra, chúng tôi có các nhân vật kết hợp để xem xét là tốt. Để biết thêm thông tin, xem các ký tự trùng lặp trong Unicode .
Các cặp thay thế: Chúng xuất hiện thường xuyên đủ trên SO, vì vậy tôi sẽ chỉ cung cấp một số liên kết ví dụ:
Khác?: