本備忘錄的狀態
本備忘錄描述了一種Internet社區的試驗協議。本備忘錄并未規定任何Internet標準,
它需要進一步進行討論和建議以得到改進。本備忘錄的發布不受限制。
版權聲明
Copyright(C)TheInternetSociety(2000).AllRightsReserved.
1.介紹
本文檔描述了Unicode/ISO-10646的UTF-16編碼方式,提出了在因特網上將UTF-16
連續流作為八位字節流(octetstream)進行傳輸的觀點,按照[CHARSET-REG]所描述的
MIME字符集進行討論,還包含了MIMEcharset參數三個值的說明:UTF-16BE(big-endian),
UTF-16LE(little-endian)以及UTF-16。
1.1背景和動機
Unicode標準[UNICODE]以及ISO/IEC10646[ISO-10646]共同定義了一整套編碼字符
(CSS),下文簡稱為Unicode,它能適應世界上絕大多數的書寫文字[WORKSHOP]。本方
案接下來要討論的UTF-16是Unicode標準編碼方式中的一種;它的特點是,能將所有預
定義的字符(BMP中的第一組)編碼為2個字節,而將其他的字符(接下來的16組)編碼為4
個字節。
Unicode標準還定義了附加的字符特性以及其他應用者所感興趣的應用細節。到目前為
止,對Unicode和ISO/IEC10646的修改都是相輔相成的,這樣字符映射系統和代碼分配
也能夠保持同步。相關的標準化委員會承諾維持這個十分有用的同步機制,同時不會讓
UTF-16需要處理超過17組以外的字符。
在字符集和語言上的IETF政策[CHARPOLICY]表明IETF協議必須能夠使用UTF-8字
符編碼架構[UTF-8]。一些產品和網絡標準已經指定使用UTF-16,這使其成為Internet上一
種重要的編碼方式。本文檔并不是對[CHARPOLICY]文檔的修改更新,而僅僅描述了
UTF-16編碼方式。
1.2專用術語
本文中所涉及的關鍵字:“必須”,“禁止”,“必需”,“應該”,“不應該”,“將要”,“將不
會”,“建議”,“也許”以及“可選”可參照RFC2119[MUSTSHOULD]中的解釋。
在本文中,字符的值用十六進制符號表示。例如,“0x013C”表示字符在CSS中的值
為316(十進制)。
2.UTF-16的定義
UTF-16在Unicode標準第三版[UNICODE]中被定義。定義的有關參考文獻可參看
ISO/IEC10646-1[ISO-10646]附錄Q。本節后面將簡單概括該定義。
在ISO10646中,每個字符被分配一個數字,Unicode將其稱為Unicode值,這個數
字和UCS-4中字符的值一樣,為簡單起見,本文將該數字稱為“字符的值”。在UTF-16編
碼中,字符根據其本身的值,用一個或兩個無符號的16位整數來表示,將這些整數線性化
以便作為字節流進行傳輸將在第3部分加以討論。
字符按照UTF-16進行編碼的規則是:
-字符的值小于0x10000的用等于該值的16位整數來表示。
-字符的值介于0x10000和0x10FFFF之間的,用一個值介于0xD800和0xDBFF(在
所謂的高8位區)的16位整數和值介于0xDC00和0xDFFF(在所謂的低8位區)的16位整
數來表示。
-字符的值大于0x10FFFF不能按照UTF-16進行編碼。
注意:在0xD800和0xDFFF間的值是特別為UTF-16預留,所以不應該將任何字符的值指
定為這個區間內的數值。
2.1UTF-16編碼
將某個字符的ISO10646的值轉換為UTF-16的編碼按照以下步驟進行。假設U是給
字符的值,小于0x10FFFF。
1) 如果U<0x10000,U的編碼就是無符號的十六位整數,值和其本身的值一樣,處理結
束。
2) 如果U等于或者小于0x10FFFF,則設U'=U-0x10000。此時,U'一定小于或者等于
0xFFFFF,也就是說,U'的值不會超過20位。
3) 分別初始化2個16位無符號的整數,W1和W2為0xD800和0xDC00。每個整數都有
10位可以用來對字符進行編碼,正好能容納U'的20位。
4) 將U'的高10位分配給W1的低10位,將U'的低10位分配給W2的低10位,處理結
束。
用數字來表示,第2步到第4步如下所示:
U'=yyyyyyyyyyxxxxxxxxxx
W1=110110yyyyyyyyyy
W2=110111xxxxxxxxxx
2.2UTF-16解碼
將單個字符從UTF-16解碼為ISO10646值的步驟如下。設W1為待解碼文字中第一個
16位的整數,設W2為跟在W1后的整數(如果有的話)。
1) 如果W1小于0xD800或者W1大于0xDFFF,字符的值U就是W1的值,處理結束。
2) 判斷W1的值是否介于0xD800和0xDBFF之間。如果不是,那么順序有誤,而且用
W1將不能解碼出任何合法字符。處理結束。
3) 如果沒有W2(也就是說,以W1結尾),或者雖然有W2,但不是介于0xDC00和0xDFFF
之間,那么順序同樣有錯。處理結束。
4) 建立一個20位的無符號整數U',將W1的低10位作為U'的高10位,將W2的低10位
作為U'的低10位。
5) 將U'的值加上0x10000以得到字符U的值,處理結束。
需要注意的是步驟2和步驟3指出了錯誤。本文檔并沒有討論有關錯誤恢復機制。當在
步驟2和步驟3中發生錯誤而導致處理中斷的時候,將U的值設為W1的值可能是比較明
智的做法,這樣有助于調用者診斷該錯誤,同時也不會丟失信息。另外還要注意的是字符串
解碼算法和上文所描述的單個字符解碼方法略有不同,如果有適當的錯誤報告或者是錯誤恢
復機制的話,發生錯誤時將不應該中斷后續的解碼操作。
3.標識UTF-16文字
本方案的附錄A包含了MIME字符集的三個注冊說明:"UTF-16BE","UTF-16LE",以
及"UTF-16"。MIME字符集表示CCS(編碼字符集)和CES(字符編碼方案)的結合。這里所說
的CCS是Unicdoe/ISO10646,而CES在三種情況下都是一致的,除了每個字符線性字
節流的順序不同,同時也是外部判別采用那種線性化方法的一種手段。
本節將討論對一個文本流應該采用三種標識中的哪一種。第4節將描述如何解釋文本流
的標識。
3.1big-endian和little-endian的定義
就過去而言,計算機有兩種方法來處理類似16位整數這樣的雙八位字節數。所謂的
"big-endian"硬件處理雙八位字節時先處理位于內存中低地址的高位字節。當將其輸出到磁
盤或者到網絡接口的時候(線性化),高位字節也就先出現在數據流中。而與此相對應的是,
"Little-endian"硬件先處理低位字節。目前來說,兩種硬件都很常見。
舉例來說,代表十進制258的無符號16位整數是0x0102。big-endian將其線性化輸出
為八位字節0x01,后面跟著0x02。而little-endian將其線性化輸出為八位字節0x02,后面
跟著0x01。接下來的C代碼片段就演示了如何將16位數按照big-endian順序寫入到文件
中,而不考慮硬件本身的字節順序。
voidwrite_be(unsignedshortu,FILEf)/*假設short為16位*/
{
putc(u>>8,f);/*輸出高字節*/
putc(u&0xFF,f);/*然后輸出低字節*/
}
雖然術語“網絡字節順序(networkbyteorder)”并沒有正式在標準文檔中作出有關定義,
但在許多RFC中該詞語都被用來表明big-endian線性化過程。盡管ISO10646采用
big-endian線性化([ISO-10646]6.3節),但是在因特網上有時候仍然使用little-endian順序。
3.2字節順序標志(BOM)
Unicode標準和ISO10646將0xFEFF定義為字符“零寬度不換行的空格”,同時一般
也認同為“字節順序標準(簡稱為BOM)”。后者暗示了該字符除了通常的在文本中作為“零
寬度不換行的空格”使用外,還有另一種可能的用處。根據Unicode第2.4節和ISO10646
附錄F(完整版)所建議的,將0xFEFF字符作為Unicode字節流中的一個“簽名”;當接收
方收到一個字節流的時候,借助這個首字節,既可以確定該字節流包含了Unicode字符,
也可以用來辨認線性化的順序。在帶有該簽名的線性化UTF-16流中,如果開始的兩個八位
字節為0xFE后面跟著0xFF的話,線性化順序就是big-endian;如果為0xFF后面跟著0xFE,
線性化順序就是little-endian。注意0xFFFE并不是一個Unicode字符,所以正好用它來作
為字節順序的標志。
很重要的一點就是,如果字符0xFEFF在字節流中的其他地方而不是首字節出現的話,
它就必須被解釋為“零寬度不換行的空格”。但這句話的反義并不總是正確的:在字節流首
位出現的字符0xFEFF可能被解釋為“零寬度不換行的空格”,而不一定總是字節順序標志。
舉例來說,如果一個處理將一個UTF-16字符串分隔為許多個部分,那么其中某個部分的子
串正好是以零寬度不換行的空格開頭的話,就可能以0xFEFF開頭。
此外,Unicode標準還建議在開始處理文本前,應該將開頭的0xFEFF字符去掉,這樣
建議的原理是因為在開始位置的這個字符可能是人為添加的編碼(一個編碼的簽名),而不
是真正意義上的“零寬度不換行的空格”。需要注意的是這樣做可能會影響在另外一個不同
層中需要依靠流中所有字符進行處理的外部處理過程(比如說一個數字簽名或對字符的計
數)。
特別地,雖然有例外情況,但在UTF-16純文本中,以0xFEFF開始的字符非??赡苁?BR>一個簽名。當連接兩個字符串的時候,將這些簽名去掉就顯得非常重要了,否則生成的字串
中的連接點上就可能包含本來沒有的“零寬度不換行的空格”。此外,有一些規范要求那些
標明為UTF-16的對象必須在開始位置保留0xFEFF字符,同時注明該簽名并不是對象本身
的組成部分。
3.3為UTF-16文字選擇標識
任何使用UTF-16文字編碼的標識程序,在明確地標識文字的時候,如果知道字符的線
性化順序,必須根據文字本身的字節順序,將文字標明為"UTF-16BE"或者"UTF-16LE"。這
能讓那些處理文字的應用程序不用研究文字本身就可以確切地知道線性化的順序。
在"UTF-16BE"字符中的文字必須按照big-endian的順序組裝UTF-16的16位字符值,
系統在標識UTF-16BE文字的時候,不應該給文字加上BOM(字節順序標準)。
在"UTF-16LE"字符中的文字必須按照little-endian的順序組裝UTF-16的16位字符值,
系統在標識UTF-16LE文字的時候,不應該給文字加上BOM(字節順序標準)。
任何使用UTF-16文字編碼的標識程序,在給文字加上明確的字符集標簽的時候,如果
不知道文字中字符的線性化順序,必須將文字標識為"UTF-16",同時應該讓文字以0xFEFF
開頭。
在必須使用"UTF-16BE"或者"UTF-16LE"的一個例外情況就是,如果文檔格式中要求為
UTF-16文字提供BOM的話,那就只需要將其標識為"UTF-16"。
4.解釋文字標識
當一個程序發現文字被標識為"UTF-16BE","UTF-16LE"或者"UTF-16"的時候,它將能
夠根據我們前文所提到的標識規則作出一些假定。這些假定將有助于程序接下來如何對文字
進行處理。
4.1解釋標識為UTF-16BE的文本
標識為UTF-16BE的文本可以被解釋為采用big-endian順序。即使首字節有BOM存在
也不會影響標識為UTF-16BE的文本的反線性化過程。如果發現0xFF后面跟著0xFE,將
意味著發生了錯誤,因為沒有0xFFFE的Unicode字符。
4.2解釋標識為UTF-16LE的文本
標識為UTF-16LE的文本可以被解釋為采用little-endian順序。即使首字節有BOM存
在也不會影響標識為UTF-16LE的文本的反線性化過程。在按照little-endian順序解釋這些
字節的時候,如果發現0xFE后面跟著0xFF,將意味著發生了錯誤,因為沒有0xFFFE的
Unicode字符。
4.3解釋標識為UTF-16的文本
標識為"UTF-16"的字符集可能是按照big-endian的順序,也可能是按照little-endian順
序進行線性化的。如果開始的兩個字節是0xFE后面跟著0xFF,那么文字可以被解釋為使
用big-endian順序。反之,如果開始的兩個字節是0xFF后面跟著0xFE,那么文字是采用
了little-endian順序。如果開始的兩個字節不是0xFE,0xFF,而同時也不是0xFF后面跟
著0xFE的話,那么文字就應該被解釋為使用big-endian順序。
所有處理標識為UTF-16的文字的應用程序,都必須能讀文字開始部分的最少兩個字節,
并且能處理這些字節以確定文字的線性化方向。處理標識為UTF-16的文字的應用程序禁止
在沒有檢查開始的兩位字節,并判斷是big-endianBOM還是little-endianBOM,或者不是
BOM的情況下就假定線性化方向。所有處理標識為UTF-16的文字的應用程序必須既能夠
解釋big-endian文字,也能夠解釋little-endian文字。
5.示例
舉例來說,讓我們假定有一個字符代表埃及語中描寫神Ra的象形文字,它的值是
0x12345。(這個字符在現有的Unicode中并不存在)。
在示例中所有的詞組中:
*=Ra
這里"*"代表Ra象形文字(0x12345)。
標識為UTF-16BE,并且不帶有BOM的文字:
D808DF45003D00520061
標識為UTF-16LE,并且不帶有BOM的文字:
08D845DF3D0052006100
采用Big-endian的文字,并且帶有BOM:
FEFFD808DF45003D00520061
采用Little-endian的文字,并且帶有BOM:
FFFE08D845DF3D0052006100
6.不同標準的版本
ISO/IEC10646經常按照出版的修正案進行更新;同樣地,我們也就有不同版本的
Unicdoe標準:1.0,1.1,2.0,2.1以及我們寫作時最新的版本3.0。每一個新版本都取代前一
個版本,但是那些應用,和一些比較重要的數據,并不會馬上進行更新。
總得來說,這些變化是增加新的字符,同時不會對舊的數據引起特別的問題。然而,
ISO/IEC10646的第五修正案刪除并擴展了韓語Hangul模塊,這可能會使那些包含舊的
Hangul字符的數據在新版本中出現問題。Unicode2.0和Unicode1.1有著同樣的不同。對
這樣一個不兼容的改變的比較正式的解釋是目前并沒有很多包含Hangul的應用。這樣的聲
明很可能是真的,但并沒有得到過證實。這樣的改變被人們稱為“韓語混亂”,有關的委員
會已經保證將來再不會出現類似的不兼容的改變。
新的版本所帶來的不兼容的改變是和MIME字符標識標簽有關,將在附錄A中進行討論。
7.IANA計劃
IANA準備根據RFC2278,并按照附錄A.1,A.2,和A.3中所提到的登記模板進行新的
字符集登記。
8.安全性考慮
正如本文第6節和附錄A中所提到的,UTF-16基于ISO10646并經常和ISO10646
字符集一并使用。處理的程序必須能夠處理那些在處理程序被設計出來的時候還沒有并定義
的字符,同時還要能夠阻止攻擊者通過發送包含未知的字符而可能帶來的對接收者的損害。
處理程序在處理任何類型,包括被編碼為UTF-16的文本的時候,必須對那些控制字符
保持警惕并作出檢查,因為這些字符可能對某個顯示終端或鍵盤進行重新編程。同樣地,處
理程序在解釋文本實體的時候(比如查找結合在其中的程序代碼),必須非常仔細,以不致
于在沒有警告接收者的情況下就執行這些代碼。
UTF-16中的文字可能會包含特殊的字符,比如“對象替換字符(0xFFFC)”,這些字符
可能會產生外部處理過程,這取決于處理程序的解釋和外來的數據流的可執行性。所產生的
外部處理過程可能會帶來一些副作用,比如允許發送一個消息來攻擊消息接收者。
那些應用UTF-16的程序必須仔細考慮安全方面的問題,如何來處理非法的UTF-16序
列(也就是說,序列中含有成對的非法字符或者是不成對的字符)。我們可以想象得到,在
某些情況下,攻擊者可能可以利用某些UTF-16處理程序,通過發送一個UTF-16語法并不
允許的八位字節序列來使其產生一些反常的行為。
9.參考文獻
[CHARPOLICY]Alvestrand,H.,"有關字符集和語言的IETF策略",BCP18,RFC
2277,January1998.
[CHARSET-REG]Freed,N.和J.Postel,"IANA字符集登記過程",BCP19,RFC2278,
January1998.
[HTTP-1.1]Fielding,R.,Gettys,J.,Mogul,J.,Frystyk,H.,
Masinter,L.,Leach,P.和T.Berners-Lee,"超文本傳輸協議--
HTTP/1.1",RFC2616,June1999.
[ISO-10646]ISO/IEC10646-1:1993.國際標準--
信息技術科技–全球化的多字節編碼字符集(UCS)–第一部分:架構
和基本的語言模塊.到目前為止已出版22個修正案和2個技術勘誤表。UTF-16在第一修
正案中的附錄Q作出了規定。其他的許多修正案仍然在標準化過程中的不同階段。目前正
在準備第二版,預計將在2000年出版。在新的版本中。UTF-16可能會在附錄C中作出描
述。
[MUSTSHOULD]Bradner,S.,"RFC中所使用的用來確定需求程度的關鍵字",BCP14,
RFC2119,March1997.
[UNICODE]Unicode聯盟,"Unicode標準–第三版",ISBN0-201-61633-5.全文發
布于:<http://www.unicode.org/unicode/standard/versions/Unicode3.0.html>.
[UTF-8]Yergeau,F.,"UTF-8,ISO10646的轉換格式",RFC2279,January
1998.
[WORKSHOP]Weider,C.,Preston,C.,Simonsen,K.,Alvestrand,H.,
Atkinson,R.,Crispin.,M.和P.Svanberg,"IAB字符集
工作小組的報告",RFC2130,April1997.
10.致謝
DeborahGoldsmith為本方案的初稿作了大量的工作。MartinDuerst提出了許多重要的
修改建議,其他需要感謝的包括:
MatiAllouche
WaltDaniels
MarkDavis
NedFreed
AsmusFreytag
LloydHonomichl
DanKegel
MurataMakoto
LarryMasinter
MarkusScherer
KeldSimonsen
KenWhistler
本方案由多人協同完成,其中某些段落摘抄自[UTF-8]。對于其他間接對本文作出過貢獻的
人均列于本文“致謝”一節。
A.字符集登記
本備忘錄將作為為三個MIME字符集進行登記[CHARSET-REG]的基礎。這些建議的字符集
是"UTF-16BE","UTF-16LE"和"UTF-16"。用這些字串標識的對象包含由ISO/IEC10646中
所列舉的文字所組成的文本,該方案包含至少截至到第5修正案的所有修正案(韓語模塊),
同時按照上文所提到的方案編碼并線性化成為一系列字節流。
需要注意的是"UTF-16BE","UTF-16LE"和"UTF-16"并不適合于描述“文字”的頂級媒體類
型。不過有個例外情況就是在采用類似MIME方案的HTTP協議中,被免除了頂級文本類
型的限制(參見HTTP1.1[HTTP-1.1]第19.4.2節)。
有一點非常引人注意的就是這里所描述的標簽并沒有包括版本識別號,通常指的是ISO/IEC
10646。這點是有意被忽略的,其中的原因如下:
MIME字符集被設計為用來給出在將收到的一系列字節解釋為字符時所需要的信息,但不提
供其他的信息(參看RFC2045[MIME],2.2節)。只要字符集標準不會作出不兼容的改變,
版本號其實毫無用處,因為當接收者收到新設定的字符而其又不認識的時候,它也不能從版
本標識里面得知什么。版本標識本身并不會對將要收到的新的字符作出任何解釋。
所以,只要標準一直保持兼容,讓標簽能夠標識版本號好象也僅僅只是外觀上的要求。但這
樣對于那些和版本有關的標簽來說卻是一個缺點:如果一個舊的應用收到由新的應用發來的
數據,并帶有未知的標簽,它將不能辨認該標簽,同時完全不能處理數據。而如果使用一個
通用的,大家都知道的標簽卻可以觸發基本上正確的數據處理過程,而這些數據相當可能并
沒有包含任何新的字符。
“韓語混亂”(ISO/IEC10646第5修正案)是一個不兼容的改變,并且和上文所描述的MIME
字符集與版本無關的原則相抵觸。但只有在數據包含了被按照Unicode1.1(或者說第5修正
案以前的ISO/IEC10646版本)編碼的韓國Hangul字符,兼容性問題才會出現。雖然仍然
有人爭論認為不會有這種數據,因而不必擔心,但是,這仍然是將這個改變認為是不兼容的
改變的主要原因。
那么,在實際操作中,應該使用一個版本號無關的標簽,這個標簽被理解為在第5修正案
以后的所有版本,并且不會發生任何不兼容的改變。就算在以后ISO/IEC10646的版本中
再有不兼容的改變,這里所定義的MIME字符集將仍然和以前的版本保持一致,除非IETE
對此再作出其他的規定。
A.1UTF-16BE的字符登記
To:ietf-charsets@iana.org
Subject:新的字符集登記
Charsetname(s):UTF-16BE
Publishedspecification(s):本方案適用于描述“文本”的MIME內容類型
top-leveltype:No
Person&emailaddresstocontactforfurtherinformation:
PaulHoffman<phoffman@imc.org>
FrancoisYergeau<fyergeau@alis.com>
A.2UTF-16LE的字符登記
To:ietf-charsets@iana.org
Subject:新的字符集登記
Charsetname(s):UTF-16LE
Publishedspecification(s):本方案適用于描述“文本”的MIME內容類型
top-leveltype:No
Person&emailaddresstocontactforfurtherinformation:
PaulHoffman<phoffman@imc.org>
FrancoisYergeau<fyergeau@alis.com>
A.3RegistrationforUTF-16
To:ietf-charsets@iana.org
Subject:新的字符集登記
Charsetname(s):UTF-16
Publishedspecification(s):本方案適用于描述“文本”的MIME內容類型
top-leveltype:No
Person&emailaddresstocontactforfurtherinformation:
PaulHoffman<phoffman@imc.org>
FrancoisYergeau<fyergeau@alis.com>
作者地址
PaulHoffman
InternetMailConsortium
127SegrePlace
SantaCruz,CA95060USA
EMail:phoffman@imc.org
FrancoisYergeau
AlisTechnologies
100,boul.Alexis-Nihon,Suite600
MontrealQCH4M2P2Canada
EMail:fyergeau@alis.com
版權說明
Copyright(C)TheInternetSociety(2000).AllRightsReserved.
Thisdocumentandtranslationsofitmaybecopiedandfurnishedto
others,andderivativeworksthatcommentonorotherwiseexplainit
orassistinitsimplementationmaybeprepared,copied,published
anddistributed,inwholeorinpart,withoutrestrictionofany
kind,providedthattheabovecopyrightnoticeandthisparagraphare
includedonallsuchcopiesandderivativeworks.However,this
documentitselfmaynotbemodifiedinanyway,suchasbyremoving
thecopyrightnoticeorreferencestotheInternetSocietyorother
Internetorganizations,exceptasneededforthepurposeof
developingInternetstandardsinwhichcasetheproceduresfor
copyrightsdefinedintheInternetStandardsprocessmustbe
followed,orasrequiredtotranslateitintolanguagesotherthan
English.
Thelimitedpermissionsgrantedaboveareperpetualandwillnotbe
revokedbytheInternetSocietyoritssuclearcase/" target="_blank" >ccessorsorassigns.
Thisdocumentandtheinformationcontainedhereinisprovidedonan
"ASIS"basisandTHEINTERNETSOCIETYANDTHEINTERNETENGINEERING
TASKFORCEDISCLAIMSALLWARRANTIES,EXPRESSORIMPLIED,
INCLUDING
BUTNOTLIMITEDTOANYWARRANTYTHATTHEUSEOFTHEINFORMATION
HEREINWILLNOTINFRINGEANYRIGHTSORANYIMPLIEDWARRANTIESOF
MERCHANTABILITYORFITNESSFORAPARTICULARPURPOSE.
致謝
感謝Internet協會給予RFC編輯部門的資金。