跳至內容

UTF-8

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書
UTF-8
語言國際
標準Unicode
分類EASCII
變長編碼
Unicode轉換格式
拓展自US-ASCII
變換/編碼ISO 10646 (Unicode)
前用UTF-1
顯示了谷歌所記錄的2001年至2012年主要編碼方法的使用情況,[1]2008年,UTF-8的使用率超過所有其他編碼方式,在2012年超過所有網頁的60%。其中ASCII only曲線包括所有僅包含ASCII字元的網頁,無論元數據中聲明如何。

UTF-88-bit Unicode Transformation Format)是一種針對Unicode可變長度字元編碼,也是一種字首碼。它可以用一至四個位元組對Unicode字元集中的所有有效編碼點進行編碼,屬於Unicode標準的一部分,最初由肯·湯普遜羅布·派克提出。[2][3]由於較小值的編碼點一般使用頻率較高,直接使用Unicode編碼效率低下,大量浪費主記憶體空間。UTF-8就是為了解決向下相容ASCII碼而設計,Unicode中前128個字元,使用與ASCII碼相同的二進制值的單個位元組進行編碼,而且字面與ASCII碼的字面一一對應,這使得原來處理ASCII字元的軟件無須或只須做少部份修改,即可繼續使用。因此,它逐漸成為電子郵件網頁及其他儲存或傳送文字優先採用的編碼方式。

自2009年以來,UTF-8一直是萬維網的最主要的編碼形式(對所有,而不僅是Unicode範圍內的編碼)(並由WHATWG宣佈為強制性的「適用於所有事物(for all things)」,[4]截止到2019年11月, 在所有網頁中,UTF-8編碼應用率高達94.3%(其中一些僅是ASCII編碼,因為它是UTF-8的子集),而在排名最高的1000個網頁中佔96%。[5] 第二熱門的多位元組編碼方式Shift JIS和GB 2312分別具有0.3%和0.2%的佔有率。[6][7][1]Internet郵件聯盟( Internet Mail Consortium, IMC)建議所有電子郵件程式都能夠使用UTF-8展示和建立郵件,[8] W3C建議UTF-8作為XML檔案和HTML檔案的預設編碼方式。[9]互聯網工程工作小組(IETF)要求所有互聯網協定都必須支援UTF-8編碼[10]互聯網郵件聯盟(IMC)建議所有電子郵件軟件都支援UTF-8編碼。[11]

歷史

[編輯]

1992年初,為建立良好的位元組串編碼系統以供多位元組字元集使用,開始了一個正式的研究。ISO/IEC 10646的初稿中有一個非必須的附錄,名為UTF。當中包含了一個供32位元字元使用的位元組串編碼系統。這個編碼方式的效能並不令人滿意,但它提出了將0-127的範圍保留給ASCII以相容舊系統的概念。

1992年7月,X/Open委員會XoJIG開始尋求一個較佳的編碼系統。Unix系統實驗室(USL)的Dave Prosser為此提出了一個編碼系統的建議。它具備可更快速實作的特性,並引入一項新的改進。其中,7位元ASCII符號只代表原來的意思,所有多位元組序列則會包含第8位元的符號,也就是所謂的最高有效位元

1992年8月,這個建議由IBMX/Open的代表流傳到一些感興趣的團體。與此同時,貝爾實驗室九號計劃作業系統工作小組的肯·湯普遜對這編碼系統作出重大的修改,讓編碼可以自我同步,使得不必從字串的開首讀取,也能找出字元間的分界。1992年9月2日,肯·湯普遜羅勃·派克一起在美國新澤西州一架餐車的餐桌墊上描繪出此設計的要點。接下來的日子,Pike及湯普遜將它實現,並將這編碼系統完全應用在九號計劃當中,及後他將有關成果反饋X/Open。

1993年1月25-29日的在聖地牙哥舉行的USENIX會議首次正式介紹UTF-8。

自1996年起,微軟CAB(MS Cabinet)規格在UTF-8標準正式落實前就明確容許在任何地方使用UTF-8編碼系統。但有關的編碼器實際上從來沒有實作這方面的規格。

結構

[編輯]

UTF-8使用一至六個位元組為每個字元編碼(儘管如此,2003年11月UTF-8被RFC 3629重新規範,只能使用原來Unicode定義的區域,U+0000到U+10FFFF,也就是說最多四個位元組):

  1. 128個US-ASCII字元只需一個位元組編碼(Unicode範圍由U+0000至U+007F)。
  2. 帶有附加符號拉丁文希臘文西里爾字母亞美尼亞語希伯來文阿拉伯文敘利亞文它拿字母則需要兩個位元組編碼(Unicode範圍由U+0080至U+07FF)。
  3. 其他基本多文種平面(BMP)中的字元(這包含了大部分常用字,如大部分的漢字)使用三個位元組編碼(Unicode範圍由U+0800至U+FFFF)。
  4. 其他極少使用的Unicode 輔助平面的字元使用四至六位元組編碼(Unicode範圍由U+10000至U+1FFFFF使用四位元組,Unicode範圍由U+200000至U+3FFFFFF使用五位元組,Unicode範圍由U+4000000至U+7FFFFFFF使用六位元組)。

對上述提及的第四種字元而言,UTF-8使用四至六個位元組來編碼似乎太耗費資源了。但UTF-8對所有常用的字元都可以用三個位元組表示,而且它的另一種選擇,UTF-16編碼,對前述的第四種字元同樣需要四個位元組來編碼,所以要決定UTF-8或UTF-16哪種編碼比較有效率,還要視所使用的字元的分佈範圍而定。不過,如果使用一些傳統的壓縮系統,比如DEFLATE,則這些不同編碼系統間的的差異就變得微不足道了。若顧及傳統壓縮演算法在壓縮較短文字上的效果不大,可以考慮使用Unicode標準壓縮格式(SCSU)。

描述

[編輯]
Unicode與UTF-8的轉換

目前有好幾份關於UTF-8詳細規格的檔案,但這些檔案在定義上有些許的不同:

  • RFC 3629 / STD 63(2003),這份檔案制定了UTF-8是標準的互聯網協定元素
  • 第四版,The Unicode Standard,§3.9-§3.10(2003)
  • ISO/IEC 10646-1:2000附加檔案D(2000)

它們取代了以下那些被淘汰的定義:

  • ISO/IEC 10646-1:1993修正案2/附加檔案R(1996)
  • 第二版,The Unicode Standard,附錄A(1996)
  • RFC 2044(1996)
  • RFC 2279(1998)
  • 第三版,The Unicode Standard,§2.3(2000)及勘誤表#1:UTF-8 Shortest Form(2000)
  • Unicode Standard附加檔案#27: Unicode 3.1(2001)

事實上,所有定義的基本原理都是相同的,它們之間最主要的不同是支援的字元範圍及無效輸入的處理方法。

Unicode字元位元被分割為數個部分,並分配到UTF-8的位元組串中較低的位元的位置。在U+0080的以下字元都使用內含其字元的單位元組編碼。這些編碼正好對應7位元的ASCII字元。在其他情況,有可能需要多達4個字元組來表示一個字元。這些多位元組的最高有效位元會設置成1,以防止與7位元的ASCII字元混淆,並保持標準的位元組主導字串運作順利。

代碼範圍
十六進制
標量值(scalar value)
二進制
UTF-8
二進制十六進制
註釋
000000 - 00007F
128個代碼
00000000 00000000 0zzzzzzz 0zzzzzzz(00-7F) ASCII字元範圍,位元組由零開始
七個z 七個z
000080 - 0007FF
1920個代碼
00000000 00000yyy yyzzzzzz 110yyyyy(C0-DF) 10zzzzzz(80-BF) 第一個位元組由110開始,接着的位元組由10開始
三個y;二個y;六個z 五個y;六個z
000800 - 00D7FF
00E000 - 00FFFF
61440個代碼 [Note 1]
00000000 xxxxyyyy yyzzzzzz 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz 第一個位元組由1110開始,接着的位元組由10開始
四個x;四個y;二個y;六個z 四個x;六個y;六個z
010000 - 10FFFF
1048576個代碼
000wwwxx xxxxyyyy yyzzzzzz 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz 將由11110開始,接着的位元組由10開始
三個w;二個x;四個x;四個y;二個y;六個z 三個w;六個x;六個y;六個z
Note 1 Unicode在範圍D800-DFFF中不存在任何字元,基本多文種平面中約定了這個範圍用於UTF-16擴展標識輔助平面(兩個UTF-16表示一個輔助平面字元)。當然,任何編碼都是可以被轉換到這個範圍,但在unicode中他們並不代表任何合法的值。

例如,希伯來語字母aleph(א)的Unicode代碼是U+05D0,按照以下方法改成UTF-8:

  • 它屬於U+0080到U+07FF區域,這個表說明它使用雙位元組,110yyyyy 10zzzzzz.
  • 十六進制的0x05D0換算成二進制就是101-1101-0000.
  • 這11位數按順序放入"y"部分和"z"部分:11010111 10010000.
  • 最後結果就是雙位元組,用十六進制寫起來就是0xD7 0x90,這就是這個字元aleph(א)的UTF-8編碼。

所以開始的128個字元(US-ASCII)只需一位元組,接下來的1920個字元需要雙位元組編碼,包括帶附加符號拉丁字母希臘字母西里爾字母科普特語字母,亞美尼亞語字母,希伯來文字母和阿拉伯字母的字元。基本多文種平面中其餘的字元使用三個位元組,剩餘字元使用四個位元組。

根據這種方式可以處理更大數量的字元。原來的規範允許長達6位元組的序列,可以覆蓋到31位元(通用字元集原來的極限)。儘管如此,2003年11月UTF-8被RFC 3629重新規範,只能使用原來Unicode定義的區域,U+0000到U+10FFFF。根據這些規範,以下位元組值將無法出現在合法UTF-8序列中:

編碼(二進制 編碼(十六進制 註釋
1100000x C0, C1 過長編碼:雙位元組序列的頭位元組,但碼點 <= 127
1111111x FE, FF 無法達到:7或8位元組序列的頭位元組
111110xx
1111110x
F8, F9, FA, FB, FC, FD 被RFC 3629規範:5或6位元組序列的頭位元組
11110101
1111011x
F5, F6, F7 被RFC 3629規範:碼點超過10FFFF的頭位元組

UTF-8編碼位元組含義

[編輯]
  • 對於UTF-8編碼中的任意位元組B,如果B的第一位為0,則B獨立的表示一個字元(ASCII碼);
  • 如果B的第一位為1,第二位為0,則B為一個多位元組字元中的一個位元組(非ASCII字元);
  • 如果B的前兩位為1,第三位為0,則B為兩個位元組表示的字元中的第一個位元組;
  • 如果B的前三位為1,第四位為0,則B為三個位元組表示的字元中的第一個位元組;
  • 如果B的前四位為1,第五位為0,則B為四個位元組表示的字元中的第一個位元組;

因此,對UTF-8編碼中的任意位元組,根據第一位,可判斷是否為ASCII字元;根據前二位,可判斷該位元組是否為一個字元編碼的第一個位元組;根據前四位(如果前兩位均為1),可確定該位元組為字元編碼的第一個位元組,並且可判斷對應的字元由幾個位元組表示;根據前五位(如果前四位為1),可判斷編碼是否有錯誤或數據傳輸過程中是否有錯誤。

設計UTF-8的理由

[編輯]

UTF-8的設計有以下的多字元組序列的特質:

  • 單位元組字元的最高有效位元永遠為0。
  • 多位元組序列中的首個字元組的幾個最高有效位元決定了序列的長度。最高有效位為110的是2位元組序列,而1110的是三位元組序列,如此類推。
  • 多位元組序列中其餘的位元組中的首兩個最高有效位元為10

UTF-8的這些特質,保證了一個字元的位元組序列不會包含在另一個字元的位元組序列中。這確保了以位元組為基礎的部份字串比對(sub-string match)方法可以適用於在文字中搜尋字或詞。有些比較舊的可變長度8位元編碼(如Shift JIS)沒有這個特質,故字串比對的演算法變得相當複雜。雖然這增加了UTF-8編碼的字串的資訊冗餘,但是利多於弊。另外,資料壓縮並非Unicode的目的,所以不可混為一談。即使在傳送過程中有部份位元組因錯誤或干擾而完全遺失,還是有可能在下一個字元的起點重新同步,令受損範圍受到限制。

另一方面,由於其位元組序列設計,如果一個疑似為字串的序列被驗證為UTF-8編碼,那麼我們可以有把握地說它是UTF-8字串。一段兩位元組隨機序列碰巧為合法的UTF-8而非ASCII的概率為32分1。對於三位元組序列的概率為256分1,對更長的序列的概率就更低了。

UTF-8的編碼方式

[編輯]

UTF-8是UNICODE的一種變長度的編碼表達方式《一般UNICODE為雙位元組(指UCS2)》,它由肯·湯普遜Ken Thompson於1992年建立,現在已經標準化為RFC 3629。UTF-8就是以8位元為單元對UCS進行編碼,而UTF-8不使用大尾序和小尾序的形式,每個使用UTF-8儲存的字元,除了第一個位元組外,其餘位元組的頭兩個位元都是以"10"開始,使文字處理器能夠較快地找出每個字元的開始位置。

但為了與以前的ASCII碼相容(ASCII為一個位元組),因此UTF-8選擇了使用可變長度位元組來儲存Unicode:

(注意:不論是Unicode (Table 3.7) [12],還是ISO 10646 (10.2 UTF-8) [13],目前都只規定了最高碼位是0x10FFFF的字元的編碼。下表中表示大於0x10FFFF的UTF-8編碼是不符合標準的。)

Unicode 和 UTF-8 之間的轉換關係表 ( x 字元表示碼點佔據的位 )
碼點的位數 碼點起值 碼點終值 位元組序列 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
  7 U+0000 U+007F 1 0xxxxxxx
11 U+0080 U+07FF 2 110xxxxx 10xxxxxx
16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  • 在ASCII碼的範圍,用一個位元組表示,超出ASCII碼的範圍就用位元組表示,這就形成了我們上面看到的UTF-8的表示方法,這樣的好處是當UNICODE檔案中只有ASCII碼時,儲存的檔案都為一個位元組,所以就是普通的ASCII檔案無異,讀取的時候也是如此,所以能與以前的ASCII檔案相容。
  • 大於ASCII碼的,就會由上面的第一位元組的前幾位表示該unicode字元的長度,比如110xxxxx前三位的二進位表示告訴我們這是個2BYTE的UNICODE字元;1110xxxx是個三位的UNICODE字元,依此類推;xxx的位置由字元編碼數的二進製表示的位填入。越靠右的x具有越少的特殊意義。只用最短的那個足夠表達一個字元編碼數的多位元組串。注意在多位元組串中,第一個位元組的開頭"1"的數目就是整個串中位元組的數目。

ASCII字母繼續使用1位元組儲存,重音文字希臘字母西里爾字母等使用2位元組來儲存,而常用的漢字就要使用3位元組。輔助平面字元則使用4位元組。

在UTF-8+BOM格式檔案的開首,很多時都放置一個U+FEFF字元(UTF-8以EF,BB,BF代表),以顯示這個文字檔案是以UTF-8編碼。

UTF-8的特性

[編輯]
UTF-8圖表說明
UTF-8
最小碼位 0000
最大碼位 10FFFF
每位元組所佔位數 8 bits
Byte order N/A
每個字元最小位元組數 1
每個字元最大位元組數 4
  • UCS字元U+0000到U+007F(ASCII)被編碼為位元組0x00到0x7F(ASCII相容),這也意味着只包含7位ASCII字元的檔案在ASCII和UTF-8兩種編碼方式下是一樣的。
  • 所有>U+007F的UCS字元被編碼為一個多個位元組的串,每個位元組都有標記位集。因此,ASCII位元組(0x00-0x7F)不可能作為任何其他字元的一部分。
  • 表示非ASCII字元的多位元組串的第一個位元組總是在0xC0到0xFD的範圍裏,並指出這個字元包含多少個位元組。多位元組串的其餘位元組都在0x80到0xBF範圍裏,這使得重新同步非常容易,並使編碼無國界,且很少受丟失位元組的影響。
  • 可以編入所有可能的231個UCS代碼
  • UTF-8編碼字元理論上可以最多到6個位元組長,然而16位元BMP字元最多只用到3位元組長。
  • Bigendian UCS-4位元組串的排列順序是預定的。
  • 位元組0xFE和0xFF在UTF-8編碼中從未用到,同時,UTF-8以位元組為編碼單元,它的位元組順序在所有系統中都是一様的,沒有位元組序的問題,也因此它實際上並不需要BOM
  • 與UTF-16或其他Unicode編碼相比,對於不支援Unicode和XML的系統,UTF-8更不容易造成問題。

UTF-8編碼的優點

[編輯]

總體來說,在Unicode字串中不可能由碼點數量決定顯示它所需要的長度,或者顯示字串之後在文字緩衝區中游標應該放置的位置;組合字元、變寬字型、不可列印字元和從右至左的文字都是其歸因。

所以儘管在UTF-8字串中字元數量與碼點數量的關係比UTF-32更為複雜,在實際中很少會遇到有不同的情形。

更詳細的說,UTF-8編碼具有以下幾點優點:

  • ASCII是UTF-8的一個子集。因為一個純ASCII字串也是一個合法的UTF-8字串,所以現存的ASCII文字不需要轉換。為傳統的擴充ASCII字元集設計的軟件通常可以不經修改或很少修改就能與UTF-8一起使用。
  • 使用標準的面向位元組的排序常式對UTF-8排序將產生與基於Unicode代碼點排序相同的結果。(儘管這只有有限的有用性,因為在任何特定語言或文化下都不太可能有仍可接受的文字排列順序。)
  • UTF-8和UTF-16都是可延伸標記式語言文件的標準編碼。所有其它編碼都必須通過顯式或文字聲明來指定。[1]頁面存檔備份,存於互聯網檔案館
  • 任何面向位元組字串搜尋演算法都可以用於UTF-8的數據(只要輸入僅由完整的UTF-8字元組成)。但是,對於包含字元記數的正則表達式或其它結構必須小心。
  • UTF-8字串可以由一個簡單的演算法可靠地辨識出來。就是,一個字串在任何其它編碼中表現為合法的UTF-8的可能性很低,並隨字串長度增長而減小。舉例說,字元值C0,C1,F5至FF從來沒有出現。為了更好的可靠性,可以使用正則表達式來統計非法過長和替代值(可以檢視W3 FAQ: Multilingual Forms頁面存檔備份,存於互聯網檔案館)上的驗證UTF-8字串的正則表達式)。
  • 與UCS-2的比較:ASCII轉換成UCS-2,在編碼前插入一個0x0。用這些編碼,會含括一些控制符,比如"或 '/',這在UNIX和一些C函數中,將會產生嚴重錯誤。因此可以肯定,UCS-2不適合作為Unicode的外部編碼,也因此誕生了UTF-8。

UTF-8 編碼的缺點

[編輯]

編寫不良的解析器

[編輯]

如果一個 UTF-8 解析器寫得很差(並且與當前標準的版本不相容),那麼它接收到一些偽 UTF-8 時會將其轉換成看似正確實則錯誤的 Unicode 輸出。處理八位表示的校驗常式可能遺漏一些資訊。

不利於正則表達式檢索

[編輯]

正則表達式可以進行很多進階的英文模糊檢索。例如,[a-h]表示 a 到 h 間所有字母。

同樣 GBK 編碼的中文也可以這樣利用正則表達式,比如在只知道一個字的讀音而不知道怎麼寫的情況下,也可用正則表達式檢索,因為 GBK 編碼是按讀音排序的。但是 Unicode 漢字不是按讀音排序的,所以不利於用正則表達式檢索。雖然正則表達式檢索並未考慮中文的多音字,但是由於中文的多音字數量不多,不少多音字還是同音不同調類型的多音字,所以大多數情況下正則表達式檢索是還可以接受的。不過 Unicode 漢字按部首排序,因此在只知道一個字的部首而不知道如何發音的情況下,UTF-8 可用正則表達式檢索而 GBK 不行。

可能無法用舊的 C 語言函式庫讀寫

[編輯]

由於UTF-8在編碼中可能有着空字元(null character,U+0000),這會導致C語言函示庫以及其延伸的程式解析失敗,因為這些舊有的程式庫使用這個字元來標記字串的結束。然而,之所以說「可能」,是因為這個字元是控制字元,理論上不會出現在 XML 等純文字檔案中。當萬不得已要使用空字元的時候,可能的解決方法是考慮使用 Java 的變種UTF-8 ——使用 0xc0 0x80 來編碼空字元。

其他

[編輯]

UTF-8 的 ASCII 字元只佔用一個位元組,比較節省空間,但是更多字元的 UTF-8 編碼佔用的空間就要多出1/2,特別是中文、日文和韓文(CJK)這樣的方塊文字,它們大多需要三個位元組。

UTF-8的衍生物

[編輯]

Windows

[編輯]

雖然不是標準,但許多Windows程式(包括Windows記事本)在UTF-8編碼的檔案的開首加入一段位元組串EF BB BF。這是位元組順序記號U+FEFF的UTF-8編碼結果。對於沒有預期要處理UTF-8的文字編輯器和瀏覽器會顯示成ISO-8859-1字串

Posix系統

[編輯]

Posix系統明確不建議使用位元組序遮罩EF BB BF[14]因為很多文字檔案期望以 「#!」(Shebang)開頭指示要執行的程式。Linux系統選擇使用Unicode規範形式Normalization Form C(NFC),即優先使用預組裝字元(precomposed character)而非組合字元序列(combining character sequence)。

2002年9月發佈的Red Hat Linux 8.0才開始正式把大多數區域設置的預設編碼設為UTF-8。此前是各種語言的但位元組編碼為主。2004年9月SuSE Linux 9.1開始,預設編碼遷移為UTF-8。

字串處理時,使用UTF-8或locale依賴的多位元組編碼情形,比使用C語言wchar_t的寬字元固定寬度編碼,要慢1至2個數量級。[14]

Java

[編輯]

在通常用法下,Java程式語言在通過InputStreamReaderOutputStreamWriter讀取和寫入串的時候支援標準UTF-8。但是,Java也支援一種非標準的變體UTF-8,供對象的序列化Java本地介面和在class檔案中的嵌入常數時使用的modified UTF-8

變種UTF-8

[編輯]

標準和變種的UTF-8有兩個不同點。第一,空字元(null character,U+0000)使用雙位元組的0xc0 0x80,而不是單位元組的0x00。這保證了在已編碼字串中沒有嵌入空位元組。因為C語言等語言程式中,單位元組空字元是用來標誌字串結尾的。當已編碼字串放到這樣的語言中處理,一個嵌入的空字元將把字串一刀兩斷。

第二個不同點是基本多文種平面之外字元的編碼的方法。在標準UTF-8中,這些字元使用4位元組形式編碼,而在修正的UTF-8中,這些字元和UTF-16一樣首先表示為代理對(surrogate pairs),然後再像CESU-8那樣按照代理對分別編碼。這樣修正的原因更是微妙。Java中的字元為16位元長,因此一些Unicode字元需要兩個Java字元來表示。語言的這個性質蓋過了Unicode的增補平面的要求。儘管如此,為了要保持良好的向下相容、要改變也不容易了。這個修正的編碼系統保證了一個已編碼字串可以一次編為一個UTF-16碼,而不是一次一個Unicode碼點。不幸的是,這也意味着UTF-8中需要4位元組的字元在變種UTF-8中變成需要6位元組。

因為變種UTF-8並不是UTF-8,所以用戶在交換資訊和使用互聯網的時候需要特別注意不要誤把變種UTF-8當成UTF-8數據。

Mac OS X

[編輯]

Mac OS X作業系統使用統一碼正規形式中的分解式標準等價(canonically decomposed Unicode),在檔案系統中使用UTF-8編碼進行檔案命名,這做法通常被稱為UTF-8-MAC。分解式標準等價中,預組合字元是被禁止使用的,必須以組合字元取代。

這種方法使分類變得非常簡單,但是會搞混那些使用預組合字元為標準、組合字元用來顯示特殊字元的軟件。Mac系統的這種NFD數據是統一碼正規形式(Unicode normalization)的一種格式。而其他系統,包括WindowsLinux,使用統一碼規範的NFC形式,也是W3C標準使用的形式。所以通常NFD數據必須轉換成NFC才能被其他平台或者網絡使用。

蘋果開發者專區有關於此問題的討論:Apple Q&A 1173頁面存檔備份,存於互聯網檔案館)。

MySQL

[編輯]

MySQL字元編碼集中有兩套UTF-8編碼實現:「utf8」和「utf8mb4」,其中「utf8」是一個字最多佔據3位元組空間的編碼實現;而「utf8mb4」則是一個字最多佔據4位元組空間的編碼實現,也就是UTF-8的完整實現。這是由於MySQL在4.1版本開始支援UTF-8編碼(當時參考UTF-8草案版本為RFC 2279)時,為2003年,並且在同年9月限制了其實現的UTF-8編碼的空間佔用最多為3位元組,而UTF-8正式形成標準化文件(RFC 3629)是其之後。限制UTF-8編碼實現的編碼空間佔用一般被認為是考慮到資料庫檔案設計的相容性和讀取最佳化,但實際上並沒有達到目的,而且在UTF-8編碼開始出現需要存入非基本多文種平面的Unicode字元(例如emoji字元)時導致無法存入(由於3位元組的實現只能存入基本多文種平面內的字元)。直到2010年在5.5版本推出「utf8mb4」來代替、「utf8」重新命名為「utf8mb3」並調整「utf8」為「utf8mb3」的別名,並不建議使用舊「utf8」編碼,以此修正遺留問題。[15][16][17][18]

參閱

[編輯]

參考文獻

[編輯]
  1. ^ 1.0 1.1 Davis, Mark. Unicode over 60 percent of the web. Official Google Blog. 2012-02-03 [2019-11-23]. (原始內容存檔於2018-08-09). 
  2. ^ Pike, Rob. UTF-8 history. 2003-04-30 [2019-11-23]. (原始內容存檔於2006-10-29). ...UTF-8 was designed, in front of my eyes, on a placemat in a New Jersey diner one night in September or so 1992...So that night Ken wrote packing and unpacking code and I started tearing into the C and graphics libraries. The next day all the code was done... .
  3. ^ Pike, Rob; Thompson, Ken. Hello World or Καλημέρα κόσμε or こんにちは 世界 (PDF). Proceedings of the Winter 1993 USENIX Conference. 1993 [2019-11-23]. (原始內容存檔 (PDF)於2017-10-11). 
  4. ^ Encoding Standard. encoding.spec.whatwg.org. [2019-11-23]. (原始內容存檔於2015-02-04) (英語). The problems outlined here go away when exclusively using UTF-8, which is one of the many reasons that is now the mandatory encoding for all things. 
  5. ^ Usage Survey of Character Encodings broken down by Ranking. w3techs.com. [2019-11-23]. (原始內容存檔於2022-01-21) (英語). 
  6. ^ Historical trends in the usage of character encodings. [2019-11-14]. 
  7. ^ UTF-8 Usage Statistics. BuiltWith. [2011-03-28]. (原始內容存檔於2021-12-07). 
  8. ^ Using International Characters in Internet Mail. Internet Mail Consortium. 1998-08-01 [2007-11-08]. (原始內容存檔於2007-10-26). 
  9. ^ Specifying the document's character encoding, HTML5.2, World Wide Web Consortium, 14 December 2017 [2018-06-03], (原始內容存檔於2019-06-13) 
  10. ^ 參考RFC 2277 section 3.1
  11. ^ Using International Characters in Internet Mail. 2007-10-26 [2018-07-27]. 原始內容存檔於2007-10-26. 
  12. ^ The Unicode Standard, Version 13.0, Chapter 3 (PDF). [2020-03-23]. (原始內容存檔 (PDF)於2021-09-20). 
  13. ^ ISO 10646标准下载页面. [2020-03-23]. (原始內容存檔於2022-01-19). 
  14. ^ 14.0 14.1 UTF-8 and Unicode FAQ for Unix/Linux by Markus Kuhn. [2005-06-16]. (原始內容存檔於2018-09-24). 
  15. ^ MySQL :: MySQL 8.0 Reference Manual :: 10.9.3 The utf8 Character Set (Alias for utf8mb3). dev.mysql.com. [2020-04-03]. (原始內容存檔於2021-10-31). 
  16. ^ MySQL :: MySQL 8.0 Reference Manual :: 10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding). dev.mysql.com. [2020-04-03]. (原始內容存檔於2022-01-13). 
  17. ^ MySQL :: MySQL 8.0 Reference Manual :: 10.9.1 The utf8mb4 Character Set (4-Byte UTF-8 Unicode Encoding). dev.mysql.com. [2020-04-03]. (原始內容存檔於2021-10-25). 
  18. ^ Hooper, Adam. In MySQL, never use “utf8”. Use “utf8mb4”.. Medium. 2019-08-19 [2020-04-03]. (原始內容存檔於2020-11-30) (英語). 

外部連結

[編輯]

統一碼聯盟出版的書

[編輯]
  • The Unicode Standard, Version 5.0, Fifth Edition, The Unicode Consortium, Addison-Wesley Professional,2006年10月27日。ISBN 0-321-48091-0
  • The Unicode Standard, Version 4.0, The Unicode Consortium, Addison-Wesley Professional,2003年8月27日。ISBN 0-321-18578-1