Unicode Normalization
Quá trình thống nhất các biểu diễn khác nhau của cùng một ký tự. Bốn dạng tồn tại: NFC, NFD, NFKC và NFKD.
Chuẩn hóa Unicode là quá trình chuyển đổi các chuỗi code point khác nhau biểu diễn cùng một ký tự thành dạng thống nhất. Trong Unicode, cùng một ký tự đôi khi có thể được biểu diễn theo nhiều cách. Ví dụ, ký tự tiếng Nhật "ga" có thể được biểu diễn bằng một code point U+304C (dạng tổ hợp sẵn) hoặc bằng "ka" (U+304B) + dấu dakuten kết hợp (U+3099) - hai code point. Mặc dù trông giống nhau, chuỗi byte của chúng khác nhau, nên so sánh chuỗi sẽ thất bại nếu không chuẩn hóa.
Có bốn dạng chuẩn hóa. NFC (Phân tách chính tắc rồi Tổ hợp chính tắc) phân tách rồi tổ hợp lại ký tự, và được khuyến nghị là tiêu chuẩn web. NFD (Phân tách chính tắc) chỉ thực hiện phân tách chính tắc, tách các ký tự kết hợp. NFKC (Phân tách tương thích rồi Tổ hợp chính tắc) bao gồm chuyển đổi tương thích như chuyển ký tự chữ số toàn chiều sang nửa chiều. NFKD (Phân tách tương thích) chỉ thực hiện phân tách tương thích. Bạn có thể tham khảo sách xử lý văn bản Unicode về chuẩn hóa chi tiết.
Trong thực tế, việc chọn dạng chuẩn hóa ảnh hưởng đáng kể đến hành vi hệ thống. Trong công cụ tìm kiếm và cơ sở dữ liệu, nếu dạng chuẩn hóa của đầu vào người dùng không khớp với dữ liệu lưu trữ, các chuỗi trông giống nhau sẽ không khớp khi tìm kiếm. Ví dụ, "ga" nhập bằng NFC bởi một người dùng và "ga" nhập bằng NFD bởi người khác được coi là chuỗi khác nhau nếu không chuẩn hóa. JavaScript cung cấp String.prototype.normalize() để chuyển đổi sang bất kỳ dạng nào, và Python cung cấp unicodedata.normalize().
Hệ thống tệp macOS (APFS và HFS+ cũ hơn) sử dụng dạng chuẩn hóa độc quyền gần với NFD, có thể gây ra vấn đề tương thích tên tệp với các hệ điều hành khác. Ví dụ, tệp có tên bằng ký tự tiếng Nhật tạo trên macOS có thể thất bại khi so sánh tên tệp khi chuyển sang Windows hoặc Linux. Git giải quyết vấn đề này bằng cài đặt core.precomposeunicode.
Một quan niệm sai lầm phổ biến là chuẩn hóa chỉ liên quan đến các ngôn ngữ cụ thể như tiếng Nhật hoặc tiếng Hàn, nhưng thực tế nó cần thiết cho nhiều ngôn ngữ bao gồm ký tự Latin có dấu phụ (é, ñ, v.v.) và dạng kết hợp tiếng Ả Rập. Ngoài ra, chuẩn hóa NFKC chuyển đổi ký tự chữ số toàn chiều sang nửa chiều, có thể vô tình thay đổi giao diện ký tự - hữu ích cho mục đích tìm kiếm nhưng cần thận trọng khi hiển thị. Bạn có thể tham khảo sách lập trình quốc tế hóa về kỹ thuật chuẩn hóa thực tế.
Từ góc độ đếm ký tự, dạng chuẩn hóa ảnh hưởng đến số code point cho cùng một ký tự, dẫn đến kết quả đếm khác nhau. Trong NFC, "ga" là 1 code point, nhưng trong NFD nó trở thành 2 code point. Để đếm ký tự chính xác, nên chuyển đổi văn bản sang dạng chuẩn hóa nhất quán trước khi đếm.