(Translated by https://www.hiragana.jp/)
UTF-16 - 维基百科,自由的百科全书 とべ转到内容ないよう

UTF-16

本页使用了标题或全文手工转换
维基百科ひゃっか自由じゆうてき百科ひゃっかぜん

UTF-16これUnicode编码层次模型もけいてきだいさん层:编码ひょう(Character Encoding Form,也称为"storage format")てきいち种实现方しきそくUnicodeしゅうてき抽象ちゅうしょう码位うつ为16长的整数せいすうそく码元てき序列じょれつよう于数すえそん储或传递。Unicodeてき码位,需要じゅよう1个或しゃ2个16长的码元らい表示ひょうじいん此这いち个变长表示ひょうじ

UTF"Unicode/UCS Transformation Format"てきくび字母じぼ缩写,そくUnicode转换为某しゅ格式かくしき。UTF-16正式せいしき定義ていぎISO/IEC 10646-1てき附錄ふろくC,而RFC2781也定義ていぎりょう相似そうじてき做法。

UTF-16描述

[编辑]

Unicodeてき编码そら间从U+0000いたU+10FFFF,共有きょうゆう1,112,064个码(code point)可用かようらいうつ。Unicodeてき编码そら间可以划ぶん为17个平めん(plane),まい个平めん包含ほうがん216(65,536)个码。17个平めんてき码位表示ひょうじ为从U+xx0000いたU+xxFFFF,其中xx表示ひょうじじゅうろく进制值从0016いた1016きょう计17个平めんだい一个平面称为基本きほん语言平面へいめん(Basic Multilingual Plane, BMP),あるしょうだいれい平面へいめん(Plane 0),其他平面へいめんしょう辅助平面へいめん(Supplementary Planes)。基本きほん语言平面へいめん內,したがえU+D800いたU+DFFFあいだてき码位だん永久えいきゅう保留ほりゅううついたUnicode。UTF-16就利用りよう保留ほりゅうらいてき0xD800-0xDFFFだんてき码位らいたい輔助平面へいめんてきてき码位進行しんこうへん碼。

从U+0000いたりU+D7FF以及从U+E000いたりU+FFFFてき码位

[编辑]

だいいち个Unicode平面へいめん(码位从U+0000いたりU+FFFF)包含ほうがんりょうさい常用じょうようてき。该平めんしょう为基本多ほんだ语言平面へいめん,缩写为BMP(Basic Multilingual Plane,BMP)。UTF-16あずかUCS-2编码这个范围ないてき码位为16とく长的单个码元,すう值等价于对应てき码位。BMPちゅうてき这些码位仅有てき以在UCS-2ちゅう表示ひょうじてき码位。

从U+10000いたU+10FFFFてき码位

[编辑]

辅助平面へいめん(Supplementary Planes)ちゅうてき码位,ざいUTF-16ちゅう编码为いち16とく长的码元(そく32もと,4ぶし),しょうさく代理だいり(Surrogate Pair),具体ぐたい方法ほうほう

UTF-16かい
lead \ trail DC00 DC01    …    DFFF
D800 10000 10001 103FF
D801 10400 10401 107FF
  ⋮
DBFF 10FC00 10FC01 10FFFF
  1. 码位减去 0x10000いたてき值的范围为20とく长的 0...0xFFFFF
  2. 高位こういてき10とくてき值(值的范围为 0...0x3FFじょう 0xD800 いただい一个码元或称作高位代理(high surrogate),值的范围 0xD800...0xDBFFよし于高代理だいり低位ていい代理だいりてき值要しょう所以ゆえん为了避免混淆こんこう使用しよう,Unicode标准现在しょうだか代理だいりぜん代理だいり(lead surrogates)。
  3. 低位ていいてき10とくてき值(值的范围也是 0...0x3FFじょう 0xDC00 いただい二个码元或称作低位代理(low surrogate),现在值的范围 0xDC00...0xDFFFよし于低代理だいり高位こうい代理だいりてき值要だい所以ゆえん为了避免混淆こんこう使用しよう,Unicode标准现在しょう低位ていい代理だいりきさき代理だいり(trail surrogates)。

上述じょうじゅつ算法さんぽう理解りかい为:辅助平面へいめんちゅうてき码位从U+10000いたU+10FFFF,きょう计FFFFF个,そく220=1,048,576个,需要じゅよう20らい表示ひょうじ。如果よう两个16长的整数せいすう组成てき序列じょれつらい表示ひょうじだいいち个整すうしょう为前导代理だいりようよう上述じょうじゅつ20てきまえ10だい个整すうしょう为后代理だいりよう上述じょうじゅつ20てききさき10。还要のうすえ16整数せいすうてき直接ちょくせつ判明はんめいぞく于前导整すう代理だいりてき值的范围(210=1024),还是きさき整数せいすう代理だいりてき值的范围(也是210=1024)。よし此,需要じゅようざい基本きほん语言平面へいめんちゅう保留ほりゅう对应于Unicodeてき2048个码,就足以容纳前导代理だいりあずかきさき代理だいりしょ需要じゅようてき编码そら间。这对于基本多ほんだ语言平面へいめん总计65536个码らい说,仅占3.125%。

よし于前导代理だいりきさき代理だいり、BMPちゅうてき有效ゆうこうてき码位,三者互不重叠,搜索そうさく简单てきいち个字编码てき一部分不可能与另一个字符编码的不同部分相重叠。这意味いみUTF-16どう(self-synchronizing)てき以通过仅检查一个码元来判定给定字符的下一个字符的起始码元。UTF-8也有やゆう类似优点,ただし许多早期そうきてき编码しき就不这样,必须从头开始分析ぶんせきぶんほん才能さいのう确定不同ふどうてき码元てき边界。

よし于最つねゆうてきざい基本きほんぶん种平めんちゅう,许多软件处理代理だいり对的部分ぶぶん往往おうおういた充分じゅうぶんてき测试。这导致了いち些长てきbugあずか潜在せんざい安全あんぜんほら,它们甚至存在そんざい于广为流行りゅうこう且评价颇だかてき应用软件ちゅう[1]

从U+D800いたU+DFFFてき码位

[编辑]

Unicode标准规定U+D800...U+DFFFてき值不对应于任なん

ただしざい使用しようUCS-2てき时代,U+D800...U+DFFF内的ないてき值被うらないようよう于某些字てきうつしゃただしただよう构成代理だいり对,许多UTF-16编码かい码还是能これよし这些符合ふごうUnicode标准てきうつせい确的べん识、转换成合なれあい规的码元[2]。按照Unicode标准,这种码元序列じょれつ本来ほんらい应算さく编码错误。

はんれい

[编辑]

以U+10437编码(𐐷)为例:

  1. 0x10437 减去 0x10000,结果为0x00437进制为 0000 0000 0100 0011 0111
  2. 分割ぶんかつ它的じょう10值和10值(使用しよう进制):0000 0000 01 00 0011 0111
  3. 添加てんか 0xD800 いたうわ值,以形成けいせい高位こうい0xD800 + 0x0001 = 0xD801
  4. 添加てんか 0xDC00 いたしも值,以形成けいせい低位ていい0xDC00 + 0x0037 = 0xDC37
  • 下表かひょう总结りょう一起示例的转换过程,颜色指示しじ码点如何いか分布ぶんぷ在所ざいしょじゅつてきUTF-16ちゅうゆかりUTF-16编码过程ちゅう加入かにゅう附加ふかてき以黑しょく显示。
普通ふつう进制 UTF-16进制 UTF-16 じゅうろく进制
だい
UTF-16BE
じゅうろく进制
UTF-16LE
じゅうろく进制
$ U+0024 0000 0000 0010 0100 0000 0000 0010 0100 0024 00 24 24 00
U+20AC 0010 0000 1010 1100 0010 0000 1010 1100 20AC 20 AC AC 20
𐐷 U+10437 0001 0000 0100 0011 0111 1101 1000 0000 0001 1101 1100 0011 0111 D801 DC37 D8 01 DC 37 01 D8 37 DC
𤭢 U+24B62 0010 0100 1011 0110 0010 1101 1000 0101 0010 1101 1111 0110 0010 D852 DF62 D8 52 DF 62 52 D8 62 DF

はんれい:UTF-16へん碼程じょ

[编辑]

假設かせつようしょうU+64321(16しん轉成てんせいUTF-16へん碼。よしため超過ちょうかU+FFFF,所以ゆえん必須ひっすへんやくなり32もと(4byte)てき格式かくしき,如下しょしめせ

V = 0x64321
Vx = V - 0x10000
= 0x54321
= 0101 0100 0011 0010 0001

Vh = 01 0101 0000 // Vxてき高位こうい份的10 bits
Vl = 11 0010 0001 // Vxてき低位ていい份的10 bits
w1 = 0xD800 //結果けっかてきまえ16もとはつはじめ值
w2 = 0xDC00 //結果けっかてき16もとはつはじめ值

w1 = w1 | Vh
= 1101 1000 0000 0000
 |       01 0101 0000
= 1101 1001 0101 0000
= 0xD950

w2 = w2 | Vl
= 1101 1100 0000 0000
 |       11 0010 0001
= 1101 1111 0010 0001
= 0xDF21

所以ゆえん這個U+64321最後さいご正確せいかくてきUTF-16へん碼應該是:

0xD950 0xDF21

而在小尾おびじょちゅうさいきさきてき编码应该

0x50D9 0x21DF

いんため這個超過ちょうかU+FFFF所以ゆえん無法むほうようUCS-2てき格式かくしきへん碼。

16しんせいへん範圍はんい UTF-16表示ひょうじ方法ほうほうしんせい 10しんせい範圍はんい ぶし數量すうりょう
U+0000 - U+FFFF xxxx xxxx xxxx xxxx - yyyy yyyy yyyy yyyy 0-65535 2
U+10000 - U+10FFFF 1101 10yy yyyy yyyy - 1101 11xx xxxx xxxx 65536-1114111 4

UTF-16おこりUTF-8こうしょざい於大おだい部分ぶぶん固定こていちょうてきぶし(2ぶしもうかそんただしUTF-16卻無法相ほうしょうようASCIIへん碼。

UTF-16てきへん碼模しき

[编辑]

UTF-16てき大尾たいびじょ小尾おびじょもうかそん形式けいしきざいよう一般いっぱんらいせつ,以Macintosh製作せいさくあるもうかそんてき文字もじ使用しよう大尾たいびじょ格式かくしき,以MicrosoftあるLinux製作せいさくあるもうかそんてき文字もじ使用しよう小尾こびじょ格式かくしき

ためりょうろう清楚せいそUTF-16ぶんけんてき大小だいしょうじょざいUTF-16ぶんけんてきひらきくび都會とかい放置ほうちいちU+FEFF作為さくいByte Order Mark(UTF-16 LE以 FF FE 代表だいひょう,UTF-16 BE以 FE FF 代表だいひょう),以顯示けんじ這個文字もじ檔案以UTF-16へん碼,其中U+FEFFざいUNICODEちゅう代表だいひょうてき意義いぎ ZERO WIDTH NO-BREAK SPACE,顧名おもえよし,它是ぼつゆうひろし也沒ゆうだんてき空白くうはく

以下いかてきれいゆうよん:「しゅ」(U+6731)、半角はんかく逗號(U+002C)、「聿」(U+807F)、「𪚥」(U+2A6A5)。

使用しようUTF-16へん碼的れい
へん名稱めいしょう へん碼次じょ へん
BOM しゅ , 𪚥
UTF-16 LE 小尾こびじょ含BOM 31 67 2C 00 7F 80 69 D8 A5 DE
UTF-16 BE 大尾たいびじょ含BOM 67 31 00 2C 80 7F D8 69 DE A5
UTF-16 LE 小尾こびじょ包含ほうがんBOM FF FE 31 67 2C 00 7F 80 69 D8 A5 DE
UTF-16 BE 大尾たいびじょ包含ほうがんBOM FE FF 67 31 00 2C 80 7F D8 69 DE A5

UTF-16あずかUCS-2てき關係かんけい

[编辑]

UTF-16なりUCS-2てきちちしゅうざいぼつゆう輔助平面へいめん(surrogate code points)まえ,UTF-16あずかUCS-2しょゆびてき同一どういつてき意思いしただしとう引入輔助平面へいめん,就稱ためUTF-16りょう現在げんざいわかゆう軟件ごえしょう自己じこ支援しえんUCS-2へん碼,其實くらゆび不能ふのう支援しえんざいUTF-16ちゅう超過ちょうか2もとぐみてきしゅうたい於小於0x10000てきUCS碼,UTF-16へん碼就とう於UCS碼。

Microsoft Windows操作そうさけい统内かく对Unicodeてき支持しじ

[编辑]

Windows操作そうさけい统内かくちゅうてき表示ひょうじ为UTF-16小尾こびじょ以正确处、显示以4节存储的ただしWindows API实际じょう仅能せい确处UCS-2そく仅以2节存储的,码位しょう于U+FFFFてきUnicode。其根みなもとただしMicrosoft C++语言 wchar_t かずすえ类型てい义为16とくてきunsigned short,这就与一よいちwchar_t かた变量对应いち宽字以存储一个Unicodeてき规定しょう矛盾むじゅん相反あいはん,Linux平台ひらだいてきGCC编译规定いちwchar_t 4节长以存储一个UTF-32,宁可なみ费了很大てきそん储空间。したれい运行于Windows平台ひらだいてきC++ほどじょ说明此点:

// 此源ぶんけんざいWindows平台ひらだいじょう必须保存ほぞん为Unicode格式かくしきそくUTF-16小尾こび
// いん包含ほうがんてき汉字“𪚥”,不能ふのうざい简体ちゅうぶんばんWindowsだま认的だい码页936(そくGBK)ちゅう表示ひょうじ
// 该汉ざいUTF-16小尾こびじょちゅうよう4个字节表示ひょうじ
// Windows操作そうさけい统能せい确显しめせ这样てきざいUTF-16需用じゅよう4表示ひょうじてき
// ただしWindows API不能ふのうせい确处这样てきざいUTF-16需用じゅよう4表示ひょうじてき判定はんてい为2个UCS-2

#include <windows.h>
#include <stdio.h>

int main()
{
	const wchar_t lwc[] = L"𪚥";

	MessageBoxW(NULL, lwc, lwc, MB_OK);

	int i = wcslen(lwc);
	printf("%d\n", i);
	int j = lstrlenW(lwc);
	printf("%d\n", j);

	return 0;
}

Windows 9xけいてきAPI仅支持しじANSIしゅうただ支持しじ部分ぶぶんてきUCS-2转换。1996ねん发布てきWindows NT 4.0てきAPI支持しじUCS-2。Windows 2000开始,Windowsけい统API开始支持しじUTF-16,并支持しじSurrogate Pair;ただし许多けい统控けん如文ほんかまちlabelとう还不支持しじsurrogate pair表示ひょうじてきかい显示なり两个Windows 7更新こうしんてきけい统已经良好地こうち支持しじりょうUTF-16,包括ほうかつSurrogate Pair。

Windows API支持しじざいUTF-16LE(wchar_t类型)あずかUTF-8(だい码页CP_UTF8)间的转码。れい如:

#include <windows.h>
int main() {
	char a1[128], a2[128] = { "Hello" };
	wchar_t w = L'页';
	int n1, n2= 5;
	wchar_t w1[128];
	int m1 = 0;

	n1 = WideCharToMultiByte(CP_UTF8, 0, &w, 1, a1, 128, NULL, NULL);
	m1 = MultiByteToWideChar(CP_UTF8, 0, a2, n2, w1, 128);
}

参考さんこう文献ぶんけん

[编辑]
  1. ^ Code in Apache Xalan 2.7.0 which can fail on surrogate pairs. Apache Foundation. [2012-03-23]. (原始げんし内容ないようそん于2011-04-23). The code wrongly assumes it is safe to use substring on the input 
  2. ^ Python 2.6 decode of UTF16 does this on Linux, and it correctly handles surrogate pairs. All "CESU" decoders do it too, though they also mistranslate correct surrogate pairs into 2 characters

外部がいぶ連結れんけつ

[编辑]