UTF-8

UTF-8（8-bit Unicode Transformation Format）是一種針對Unicode的可變寬度編碼以及字元編碼，也是一種前綴碼。它可以用一至四個字節對Unicode字符集進行編碼，屬於Unicode標準的一部分，最初由肯·湯普遜和羅布·派克提出。由於直接使用Unicode編碼效率低下，大量浪費內存空間。UTF-8就是為了解決這個問題而設計出來，Unicode中前128個字符，使用與ASCII碼相同的二進位值的單個字節進行編碼，而且字面與ASCII碼的字面一一對應，這使得原來處理ASCII字元的軟體無須或只須做少部份修改，即可繼續使用。因此，它逐漸成為電子郵件、網頁及其他儲存或傳送文字優先採用的編碼方式。

自2009年以來，UTF-8一直是全球資訊網的最主要的編碼形式（對所有，而不僅是Unicode範圍內的編碼）（並由WHATWG宣布為強制性的「適用於所有事物(for all things)」，截止到2019年11月，在所有網頁中，UTF-8編碼應用率高達94.3%（其中一些僅是ASCII編碼，因為它是UTF-8的子集），而在排名最高的1000個網頁中占96％。其它的多字節編碼方式如Shift JIS和GB 2312僅有0.3％和0.2％的占有率。Internet郵件聯盟（Internet Mail Consortium, IMC）建議所有電子郵件程序都能夠使用UTF-8展示和創建郵件， W3C建議UTF-8作為XML文件和HTML文件的默認編碼方式。網際網路工程工作小組（IETF）要求所有網際網路協議都必須支持UTF-8編碼。網際網路郵件聯盟（IMC）建議所有電子郵件軟體都支持UTF-8編碼。

## 歷史

國際標準化組織（ISO）為建立供多位元組字元集使用的良好的位元組串編碼系統，於1989年著手制定一個通用多字節字符集。初稿ISO/IEC 10646中包含了一個名為UTF-1的非必要附件，該附件提供了供32位元的字元使用的位元組串編碼系統。儘管此編碼方式的性能並不令人滿意，但它提出的將0-127的範圍保留給ASCII以相容舊系統的概念意義重大。

1992年7月，X/Open委員會的主要關注系統間的互操作性（Interoperability）的XoJIG部門正在尋求一個更好的編碼系統。Unix系統實驗室（USL）的Dave Prosser為此提交了一份提案，意圖構建一個具備可更快速實作性的編碼系統，並引入一項新的改進。其中，7位元的ASCII符號僅代表其原來對應的字符，而所有多位元組序列則會包含第8位元的符號，也就是所謂的最高有效位元。

1992年8月，這份提案由IBM的X/Open代表分發給各相關方。與此同時，貝爾實驗室九號計畫作業系統工作小組的肯·湯普遜對這編碼系統作出重大修改，讓編碼可以自我同步，這使得即使不從字串的開首讀取，也能找出字符間的分界。1992年9月2日，肯·湯普遜和羅勃·派克一起在美國新澤西州一架餐車的餐桌墊上描繪出了此項設計的要點。隨後數日，派克及湯普遜將其實現並完全應用在九號計畫當中，後他們將此項成功的設計提交至了X/Open，X/Open則接受了這項設計，作為FSS-UTF的規範。

1993年1月25-29日的在聖地牙哥舉行的USENIX會議首次正式介紹UTF-8。1998年1月，網際網路工程任務組（IETF）在RFC 2277（BCP 18）中的字符集和語言政策中採用了UTF-8，用於未來的網際網路標準工作，取代了舊RFC中的諸如Latin-1之類的單位元組字符集（SBCS）。

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

2003年11月，UTF-8爲符合UTF-16字元編碼的約束受到RFC 3629的限制：明確禁止對應於高低代理字元的碼點刪除超3%的三位元組序列，以U+10FFFF結尾刪除超過48%的四位元組序列以及所有五位元組和六位元組序列。

## 結構

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

- 128個US-ASCII字符只需一個位元組編碼（Unicode範圍由U+0000至U+007F）。
- 帶有附加符號的拉丁文、希臘文、西里爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及它拿字母則需要兩個位元組編碼（Unicode範圍由U+0080至U+07FF）。
- 其他基本多文種平面（BMP）中的字元（這包含了大部分常用字，如大部分的漢字）使用三個位元組編碼（Unicode範圍由U+0800至U+FFFF）。
- 其他極少使用的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）。

## 描述

<image>

目前有好幾份關於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 - 00007F128個代碼｜00000000 00000000 0zzzzzzz｜0zzzzzzz（00-7F）｜ASCII字元範圍，位元組由零開始

七個z｜七個z

000080 - 0007FF1920個代碼｜00000000 00000yyy yyzzzzzz｜110yyyyy（C0-DF） 10zzzzzz（80-BF）｜第一個位元組由110開始，接著的位元組由10開始

三個y；二個y；六個z｜五個y；六個z

000800 - 00D7FF 00E000 - 00FFFF61440個代碼 D800｜00000000 xxxxyyyy yyzzzzzz｜1110xxxx（E0-EF） 10yyyyyy 10zzzzzz｜第一個位元組由1110開始，接著的位元組由10開始

四個x；四個y；二個y；六個z｜四個x；六個y；六個z

010000 - 10FFFF1048576個代碼｜000wwwxx xxxxyyyy yyzzzzzz｜11110www（F0-F7） 10xxxxxx 10yyyyyy 10zzzzzz｜將由11110開始，接著的位元組由10開始

三個w；二個x；四個x；四個y；二個y；六個z｜三個w；六個x；六個y；六個z

D800 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位元組序列的頭字節

111110xx1111110x｜F8, F9, FA, FB, FC, FD｜被RFC 3629規範：5或6位元組序列的頭字節

111101011111011x｜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)，還是ISO 10646 (10.2 UTF-8)，目前都只規定了最高碼位是0x10FFFF的字元的編碼。下表中表示大於0x10FFFF的UTF-8編碼是不符合標準的。）

碼點的位數｜碼點起值｜碼點終值｜字節序列｜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

最小碼位｜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都是可擴展標記語言文檔的標準編碼。所有其它編碼都必須通過顯式或文本聲明來指定。
- 任何面向字節的字串搜索算法都可以用於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`。因為很多文本文件期望以 「#!」（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個數量級。

### Java

在通常用法下，Java程序語言在通過java/io和java/io讀取和寫入串的時候支持標準UTF-8。但是，Java也支持一種非標準的變體UTF-8，供對象的序列化，Java本地界面和在class文件中的嵌入常數時使用的java/io。

#### 變種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）的一種格式。而其他系統，包括Windows和Linux，使用統一碼規範的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草案版本為）時，為2003年，並且在同年9月限制了其實現的UTF-8編碼的空間占用最多為3位元組，而UTF-8正式形成標準化文檔是其之後。限制UTF-8編碼實現的編碼空間占用一般被認為是考慮到資料庫文件設計的兼容性和讀取最優化，但實際上並沒有達到目的，而且在UTF-8編碼開始出現需要存入非基本多文種平面的Unicode字符（例如emoji字符）時導致無法存入（由於3位元組的實現只能存入基本多文種平面內的字符）。直到2010年在5.5版本推出「utf8mb4」來代替、「utf8」重命名為「utf8mb3」並調整「utf8」為「utf8mb3」的別名，並不建議使用舊「utf8」編碼，以此修正遺留問題。

## 參閱

- Alt碼
- ASCII
- 位元組順序記號
- Comparison of email clients#Features
- Comparison of Unicode encodings
- Character encodings in HTML
- ISO/IEC 8859
- GB18030
- iconv
- Unicode and e-mail
- Unicode and HTML
- 通用字符集
- UTF-16
- UTF-9和UTF-18
- 寬字元

## 外部連結

- RFC 3629：UTF-8標準
- RFC 2277：IETF policy on character sets and languages
- Rob Pike tells the story of UTF-8's creation
- Original UTF-8 paper
- UTF-8 test pages by University Hannover and the World Wide Web Consortium
- Unix/Linux: UTF-8和Unicode的常見問題集， Linux Unicode HOWTO， UTF-8 and Gentoo
- The Unicode/UTF-8-character table displays UTF-8 in a variety of formats（with Unicode and HTML encoding information）
- Online Tool for URL encoding/decoding according to RFC 3986 and RFC 3629（JavaScript，GPL）
- UTF-8測試頁
- UTF-8

### 由統一碼聯盟出版的書

- 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

## 基本資料

- 標準：Unicode
- 語言：國際
- 分類：EASCII、變長編碼、Unicode轉換格式
- 變換/編碼：ISO 10646 (Unicode)
- 拓展自：US-ASCII
- 前用：UTF-1