2010-08-24 33 views
6

UTF-8 có thể mã hóa chuỗi 5 hoặc 6 byte, cho phép mã hóa tất cả các ký tự Unicode không? Tôi đang nhận được các tiêu chuẩn xung đột. Tôi cần có khả năng hỗ trợ mỗi ký tự Unicode, không chỉ trong phạm vi U + 0000..U + 10FFFF.Có 6 chuỗi octet UTF-8 hợp lệ không?

(Tất cả các dấu ngoặc kép là từ RFC 3629)

Phần 3:

Trong UTF-8 ký tự từ + 0000..U + 10FFFF phạm vi U (UTF-16 phạm vi truy cập) được mã hóa bằng các chuỗi từ 1 đến 4 octet. Chỉ chỉ octet của một "chuỗi" của một chuỗi có bit thứ tự cao hơn được đặt thành 0, 7 bit còn lại được sử dụng để mã hóa số ký tự. Trong một chuỗi octet số , n> 1, octet ban đầu có n thứ tự cao hơn bit được đặt thành 1, tiếp theo là bit được đặt thành 0. Số bit còn lại của octet đó chứa bit từ số của ký tự là được mã hóa. Tất cả octet sau đây đều có bit thứ tự cao hơn được đặt thành 1 và bit sau được đặt thành 0, để 6 bit trong mỗi bit chứa bit từ ký tự được mã hóa.

Vì vậy, không phải tất cả các ký tự có thể được mã hóa bằng UTF-8? Điều này có nghĩa là tôi không thể mã hóa các ký tự từ các mặt phẳng khác với BMP?

Phần 2:

Octet giá trị C0, C1, F5 để FF bao giờ xuất hiện.

Điều này có nghĩa là chúng tôi không thể mã hóa giá trị UTF-8 với 5 hoặc 6 octet (hoặc thậm chí một số có 4 giá trị không nằm trong phạm vi trên)?

Phần 12:

hạn chế phạm vi của các nhân vật để 0000-10FFFF (phạm vi UTF-16 thể truy cập).

Nhìn vào RFC trước xác nhận điều này ... chúng đã giảm phạm vi ký tự.

Phần 10:

Một vấn đề an ninh xảy ra khi mã hóa sang UTF-8: ISO/IEC 10646 mô tả về UTF-8 cho phép số nhân vật mã hóa lên đến U + 7FFFFFFF, năng suất chuỗi lên đến 6 byte. Do đó, có nguy cơ tràn bộ đệm nếu phạm vi của các số ký tự không phải là giới hạn rõ ràng với U + 10FFFF hoặc nếu kích thước bộ đệm không đưa vào số tính khả năng của chuỗi 5 và 6 byte.

Vì vậy, các chuỗi này được phép theo định nghĩa ISO/IEC 10646, nhưng không được định nghĩa RFC 3629? Tôi nên theo dõi cái nào?

Xin cảm ơn trước.

Trả lời

7

Không có Unicode ký tự vượt quá 10FFFF, BMP bao gồm 0000 thông qua FFFF.

UTF-8 được xác định rõ cho 0-10FFFF.

+2

Cảm ơn, điều đó có ý nghĩa. Điều này có nghĩa là tôi chỉ cần phải lo lắng về chuỗi UTF-8 dài hơn 4 octet, với bất cứ điều gì còn là một lỗi? –

+0

@PatrickNiedzielski Có, nhưng bạn phải coi chúng là lỗi ('MUST'). –

+0

@devio, Điều gì sẽ xảy ra trong các phiên bản tương lai của Unicode khi chúng mở rộng nó? – Pacerier

1

Cả UTF-8 và UTF-16 đều cho phép mã hóa tất cả các ký tự Unicode. Những gì UTF-8 không được phép làm là mã hóa nửa trên và dưới thay thế (mà UTF-16 sử dụng) hoặc các giá trị trên U + 10FFFF, không hợp pháp Unicode.

Lưu ý rằng BMP kết thúc tại U + FFFF.

0

Tôi sẽ phải nói không: Điểm mã Unicode hợp lệ cho phạm vi [0, 0x10FFFF] và các bản đồ đó đến 1-4 octet. Vì vậy, nếu bạn đã đi qua một điểm mã hóa mã hóa 5 hoặc 6 octet UTF-8, nó không phải là một điểm mã hợp lệ - chắc chắn không có gì được gán ở đó. Tôi hơi bối rối vì tại sao họ lại có tiêu chuẩn ISO - tôi không thể tìm được lời giải thích.

Nó làm bạn ngạc nhiên, tuy nhiên, nếu có lẽ một ngày nào đó trong tương lai, họ sẽ mở rộng qua U + 10FFFF. 0x10FFFF cho phép hơn một triệu ký tự, nhưng có rất nhiều ký tự ở đó, và nó sẽ phụ thuộc vào số lượng cuối cùng được mã hóa. (Vì lợi ích của sanity, chúng ta hãy hy vọng không, một triệu ký tự là rất nhiều!) UTF-32 có thể xử lý nhiều điểm mã, và như bạn đã phát hiện, UTF-8 có thể. Thực sự là UTF-16 không may mắn - nhiều cặp thay thế sẽ cần ở đâu đó trong quang phổ của các điểm mã.

+2

ISO ban đầu có ý định giới thiệu mã hóa ký tự 31 bit của riêng chúng. UTF-8 được thiết kế xung quanh khả năng đó. – dan04

+1

Với tôi, có vẻ như Unicode đang cố gắng lấp đầy phần còn lại của các điểm lập trình ... rằng họ có nhiều hơn những gì họ biết phải làm gì. Ví dụ: có một khối cho khối chơi Mahjong. Tuy nhiên, chắc chắn có một số nhân vật hữu ích bên ngoài BMP mà tôi cần hỗ trợ. Tuy nhiên, phần lớn trong số đó là rác rưởi. Điều đó khiến tôi tự hỏi tại sao họ không chấp nhận các nhân vật của Klingon một lúc nữa. –

+0

@ dan04: Khá như vậy. Đó là lý do tại sao bạn có thể có các ký tự trừu tượng của các điểm mã cao hơn nhiều so với 0x10_FFFF là bạn không sử dụng chúng để trao đổi UTF. (Đôi khi chúng được gọi là * supers * hoặc * supras *.) Ví dụ: in-in 'chr (0xFFF_FFFF_FFFF)' in '17592186044415'. Điều này có thể khá tiện dụng. – tchrist

Các vấn đề liên quan