2011-03-13 37 views
46

我從來沒有理解UTF-16編碼的要點。如果您需要將字符串視爲隨機訪問(即代碼點與代碼單元相同),那麼您需要使用UTF-32,因爲UTF-16仍然是可變長度。如果你不需要這個,那麼與UTF-8相比,UTF-16看起來像是一個巨大的空間浪費。 UTF-16相對於UTF-8和UTF-32的優點是什麼?Windows和Java爲什麼使用它作爲它們的本地編碼?UTF-16的意義何在?

+0

也許你可以改變你的問題,不要那麼主觀和議論? – Gabe 2011-03-13 20:29:35

+4

如果只有UTF-32纔是真的......玩5分鐘,結合字符http://en.wikipedia.org/wiki/Combining_character和告訴我多少「隨機」的一切是:-) – xanatos 2011-03-13 20:36:26

回答

36

當Windows NT被設計UTF-16沒(NT 3.51誕生於1993年,而UTF-16誕生於1996年,採用Unicode 2.0標準);相反,當時UCS-2足以容納Unicode中的每個字符,因此1碼點= 1的碼單元等值實際上是真的 - 字符串不需要可變長度的邏輯。

後來他們轉移到了UTF-16,以支持整個Unicode字符集;但是他們無法移動到UTF-8或UTF-32,因爲這會破壞API接口中的二進制兼容性(等等)。

至於Java,我不太確定;自從它在〜1995年發佈以來,我懷疑UTF-16已經在空中(即使它還沒有標準化),但我認爲與基於NT的操作系統的兼容性可能在它們的選擇中起了一定作用(連續UTF-8 < - >每次調用Windows API時,UTF-16轉換都會引起一些放緩)。


編輯

維基百科解釋說,即使是Java中以同樣的方式去:原來它支持UCS-2,但在J2SE 5.0移到UTF-16。

因此,一般情況下,當您在某些API/Framework中看到使用UTF-16時,這是因爲它以UCS-2開頭(以避免字符串管理算法出現併發症),但它轉移到UTF-16以支持代碼點在BMP之外,仍然保持相同的代碼單元大小。

+1

你可以看看http://en.wikipedia.org/wiki/UTF-16/UCS-2 – mozillanerd 2011-03-13 20:47:22

4

UTF-16覆蓋整個BMP單個單元 - 因此,除非您需要BMP以外的稀有字符,否則UTF-16每個字符有效2個字節。 UTF-32需要更多的空間,UTF-8需要可變長度的支持。

+0

我會將必要的維基引用添加到UTF-32,這解釋了所有缺點:http://en.wikipedia。org/wiki/UTF-32/UCS-4 – xanatos 2011-03-13 20:37:57

+11

@Erik - 你可能會說UTF-8每個字符有效一個字節......除非你需要ASCII以外的稀有字符。實際上,UTF-16的長度和UTF-8一樣長。 – SigueSigueBen 2012-06-21 17:25:46

+0

我使用日文字符(或法文),我們實際上正在考慮使用UTF-16。我希望這個討論包括這些變量是如何變化的,以及如果使用UTF-16可以針對不同程度的非ASCII性進一步優化 – Aki 2014-06-11 08:53:17

1

UTF16通常用作直接映射到多字節字符集,即onyl原始的0-0xFFFF分配的字符。

這讓你兩全其美的,你有固定的字符大小,但仍然可以打印的所有字符的人可能使用(除外正統克林貢religous腳本)

+3

除非來自香港,否則即使是基本的粵語句子也可能需要BMP以外的字符。除此之外,沒有什麼樂趣可以讓程序拒絕一些有效的字符,而無法讓最終用戶看到。 – prosfilaes 2012-05-25 07:19:14

1

UTF-16允許將所有基本多語言平面(BMP)表示爲單個代碼單元。超出U + FFFF的Unicode代碼點由代理對代表。

有趣的是,Java和Windows(以及其他使用UTF-16的系統)都在代碼單元級而不是Unicode代碼點級別上運行。因此,由單個字符U + 1D122(MUSICAL SYMBOL F CLEF)組成的字符串在Java中被編碼爲「\ ud824 \ udd22」和"\ud824\udd22".length() == 2(而不是1)。所以這是一種黑客行爲,但事實證明,字符不是可變長度的。

UTF-16優於UTF-8的優點是,如果UTF-8使用相同的hack,則會放棄太多。

+4

我認爲(是的,我認爲:-))如果程序員必須知道變長,世界纔會變得更好字符,而不是發現它們「隨便」(因爲現在,程序員可以活着幾年而不知道代碼點可能很長2,如果所有代碼都是UTF-8,他可以在幾個月內將頭部保存在地球上: - )) – xanatos 2011-03-14 20:01:45

12

除了向後兼容答覆之外,指示UTF-16相對於UTF-8的優勢的答覆沒有任何意義。

那麼,我的評論有兩個注意事項。 Erik指出:「UTF-16以單個單位覆蓋整個BMP - 因此,除非您需要BMP以外的稀有字符,否則UTF-16每個字符有效2個字節。」

買者1)

。如果你可以肯定,你的應用程序將永遠不需要在BMP之外的任何字符,那你寫它使用任何庫代碼將永遠不會與任何應用程序一起使用這將不會需要BMP以外的字符,那麼你可以使用UTF-16,並編寫代碼來隱含假設每個字符的長度都是兩個字節。

這似乎非常危險(實際上,愚蠢)。

它可能永遠只有一個字符在BMP之外,應用程序或庫代碼可能在某些時候需要處理,假定所有UTF-16字符長度爲兩個字節的代碼都會中斷。

因此,必須編寫檢查或操縱UTF-16的代碼來處理需要超過2個字節的UTF-16字符的情況。

因此,我「解僱」這個警告。

因此,與UTF-8(兩者都必須處理可變長度字符的代碼)相比,UTF-16的編碼並不簡單。

買者2)

UTF-16可能是計算效率更高,在某些情況下,如果適當地寫入。

像這樣:假設某些長字符串很少被修改,但經常被檢查(或更好的,從未修改一次構建 - 即,一個字符串生成器創建不可修改的字符串)。可以爲每個字符串設置一個標誌,指示該字符串是否僅包含「固定長度」字符(即,不包含長度不完全是兩個字節的字符)。標誌爲真的字符串可以使用假定固定長度(2字節)字符的優化代碼進行檢查。

空間效率如何?

對於A)字符,UTF-16顯然比UTF-8更有效,UTF-16比UTF-8需要更少的字節來編碼。

對於UTF-8編碼比UTF-16需要更少字節的B)字符,UTF-8顯然更爲高效。

除了非常「專業」的文本,計數(B)可能遠遠超過計數(A)。