2010-08-24 24 views
6

UTF-8可以編碼5或6字節的序列,允許編碼所有的Unicode字符嗎?我遇到了衝突的標準。我需要能夠支持每個Unicode字符,而不僅僅是U + 0000..U + 10FFFF範圍內的那些字符。6個八位字節的UTF-8序列是否有效?

(股價從RFC 3629

第3部分:

在UTF-8,從U + 0000..U + 10FFFF範圍字符(UTF-16 訪問範圍)使用1到4個八位字節的序列進行編碼。只有一個「序列」的八位字節具有設置爲0的高位比特,其餘的7比特用於編碼字符編號。在n個八位字節的序列中,n> 1時,初始八位字節將n個高位 比特設置爲1,隨後將比特設置爲0.其餘位( )中的八位字節包含來自該數字的比特的字符被編碼爲 。以下八位組的所有高位比特都被設置爲 1,並且隨後的比特被設置爲0,每個比特中的6比特包含來自要編碼的字符的 比特。

那麼不是所有可能的字符都可以用UTF-8編碼嗎?這是否意味着我不能對不同於BMP的字符進行編碼?

第2部分:

的八位組值C0,C1,F5至FF永遠不會出現。

這意味着我們無法使用5或6個八位字節(或甚至一些4個不在上述範圍內)編碼UTF-8值?

第12節:

限制字符0000-10FFFF的範圍(UTF-16 訪問範圍)。

看着前面的RFC證實了這一點...他們減少了字符的範圍。

第10節:編碼爲UTF-8時

發生另一個安全問題:的ISO/IEC 10646描述UTF-8允許編碼的字符數達 U + 7FFFFFFF,得到了序列到6個字節。因此,如果字符數範圍不是明確限制爲U + 10FFFF,或者如果緩衝區大小沒有考慮到 說明5字節和6字節序列的可能性,則存在緩衝區溢出的風險。

因此,根據ISO/IEC 10646定義允許這些序列,但不允許RFC 3629定義?我應該遵循哪一個?

在此先感謝。

回答

7

沒有Unicode字符超過10FFFF,BMP覆蓋0000到FFFF。

UTF-8對於0-10FFFF是明確定義的。

+2

謝謝,這是有道理的。這是否意味着我只需要擔心長度超過4個八位字節的UTF-8序列,並且任何更長的時間都是錯誤? – 2010-08-24 20:23:32

+0

@PatrickNiedzielski是的,但你必須把它們當作錯誤('MUST')。 – 2016-08-27 17:37:43

+0

@devio,當他們展開它時,在將來的Unicode版本中怎麼樣? – Pacerier 2017-03-20 09:20:19

1

UTF-8和UTF-16都允許對所有Unicode字符進行編碼。 UTF-8不允許做的是編碼上下兩個代理半(UTF-16使用)或高於U + 10FFFF的值,這是不合法的Unicode。

請注意,BMP在U + FFFF處結束。

0

我不得不說:Unicode碼點對於範圍[0,0x10FFFF]是有效的,並且那些映射到1-4個八位字節。因此,如果您確實遇到了5或6個字節的UTF-8編碼的代碼點,那麼這不是一個有效的代碼點 - 這裏肯定沒有分配。我有點困惑,爲什麼他們在ISO標準 - 我找不到解釋。

然而,它確實讓人想知道,如果在將來某一天,它們會擴展到U + 10FFFF。 0x10FFFF允許超過一百萬個字符,但是那裏有很多字符,並且這取決於最終被編碼多少。 (爲了理性,我們希望不會,一百萬個字符是很多的!)UTF-32可以處理更多的代碼點,正如你發現的那樣,UTF-8可以。它確實是UTF-16,它的運氣不好 - 在代碼點範圍的某個地方需要更多的代理對。

+2

ISO本​​來打算介紹他們自己的31位字符編碼。 UTF-8是圍繞這種可能性而設計的。 – dan04 2010-08-31 03:39:36

+1

對我來說,似乎Unicode正在試圖填補其餘的代碼點......他們比他們知道如何處理更多。例如:麻將牌有一個塊。但是,我需要支持BMP外部的一些有用的字符。雖然他們大多數都是垃圾。 這讓我想知道他們爲什麼不接受克林貢角色。 – 2010-09-01 15:22:00

+0

@ dan04:確實如此。這就是爲什麼您可以使用比0x10_FFFF更高的代碼點的抽象字符,因爲您沒有將它們用於UTF交換。 (有時候這些被稱爲* supers *或* supras *)。例如,'perl -le'print ord chr(0xFFF_FFFF_FFFF)''打印'17592186044415'。這可以非常方便。 – tchrist 2011-02-13 19:30:23

相關問題