首先我們來思考UTF-16的設(shè)計思路:
我們知道Unicode的范圍為0x0~0x10FFFF
首先是BMP區(qū)間,也就是0x0~0xFFFF這段區(qū)間,正好16位就可以表示,也兼容,兩全其美
那么超過BMP區(qū)間的怎么辦呢?
也就是0xFFFF~0x10FFFF這段,我們先看這段區(qū)間有多少個碼位,0x10FFFF-0xFFFF=0x100000,那么這個十六進制表示的十進制也就是:1048576個碼位
我們既然16位存不下,那肯定就是32位存咯,這個32能理解為什么不?不理解?是因為計算機只能以2的倍數(shù)拓展,如果不這么設(shè)計,就沒辦法解析。長短不一,不符合設(shè)計思路
32位來存這些數(shù)字,那么我們需要怎么存下呢,簡單的思考過后,大家認為應(yīng)該分開存儲,也就是將32位分開前16位和后16位,每個16位各存一半
那么每一半存的就是1024(由來:√1048576=1024,也就是1024*1024=1048576),1024代表的是2的10次冪,也就是10位二進制數(shù)
這樣就知道了,32位二進制數(shù)字中,前后16位中各存10位就夠用了,但是剩余的6位用來干什么呢?
和UTF-8的設(shè)計一樣,為了讓識別字符串變得容易(從文本的任意位置開始,均能區(qū)分一個字符的起始),這里是不是有點兒蒙?
舉個栗子:
假設(shè):
0000 0001 代表A
0000 0010 代表B
0000 0001 ,0000 0001 代表 X
0000 0010 ,0000 0001 代表Z
那么 ABXZ就是
0000 0001 ,0000 0010 , 0000 0001 ,0000 0001 , 0000 0010,0000 0001
A B X Z
但是讓你從中間開始讀取,當(dāng)你讀到X的時候,你不知道他是X還是 AB,這樣就很麻煩,你需要設(shè)置標(biāo)志,來讓16位的數(shù)據(jù)的前8或后8不會和單個8位的重復(fù)
可以這樣設(shè)計:
0xxx xxxx 代表0~2^7
11xx xxxx ,10xx xxxx 代表其他的
這樣就能區(qū)分開了,當(dāng)你讀到11開頭的,就代表他是16位的前8,10開頭代表16位的后8
歐了,有了這個思路,我們就知道怎么設(shè)計剛才的那個6位了,當(dāng)然是通過這6位來區(qū)分這16位數(shù)字代表的位置
也就是UTF-16中,表示數(shù)據(jù)有單16位和雙16位(32位)兩種,那么我們設(shè)計成單16位和32位中的前16位和后16位這三個16位完全不會重復(fù),那么我們就能隨時讀到一組16位,就能知道他是單16還是前16還是后16
舉個栗子:
根據(jù)上方信息,要求我們通過前6位來區(qū)分數(shù)據(jù),那么前6位就是2^6=64,也就是開頭數(shù)字的區(qū)間
我們設(shè)定如下:
54開頭的為32位的前16位
55開頭的為32位的后16位
其他開頭的為單16位
這樣我們就能區(qū)分開這三個16位了,在讀取文檔中的任意位置,都能隨意區(qū)分出間隔咯
那么54開頭的數(shù)據(jù)區(qū)間是多少呢,就是1101 10xx xxxx xxxx,區(qū)間就是D800~DBFF
那么55開頭的數(shù)據(jù)區(qū)間是多少呢,就是1101 11xx xxxx xxxx,區(qū)間就是DC00~DFFF
為了配合UTF-16,Unicode中也將這兩個區(qū)間屏蔽掉,不允許分配任何字符
下方為比較官方的關(guān)于UTF-16的編碼詳解
參考文獻:
https://en.wikibooks.org/wiki/Unicode/Character_reference/D000-DFFF
根據(jù)參考文獻中所示,D800~DFFF為專門提供給UTF-16專用,原文如下:
Unicode range D800–DFFF is used for surrogate pairs in UTF-16 (used by Windows) and CESU-8 transformation formats,
Unicode范圍D800-DFFF用于UTF-16(由Windows使用)和CESU-8轉(zhuǎn)換格式的代理對,
allowing these encodings to represent the supplementary plane code points, whose values are too large to fit in 16 bits.
允許這些編碼表示輔助平面代碼點,其值太大,無法容納16位。
A pair of 16-bit code points — the first from the high surrogate area (D800–DBFF),and the second from the low surrogate area (DC00–DFFF) — are combined to form a 32-bit code point from the supplementary planes.
一對16位代碼點 - 第一個來自高代理區(qū)域(D800-DBFF),和來自低代理區(qū)域(DC00-DFFF)的第二個組合以從輔助平面形成32位代碼點。
Unicode and ISO/IEC 10646 do not assign actual characters to any of the code points in the D800–DFFF range — these code points only have meaning when usedin surrogate pairs.
Unicode和ISO / IEC 10646不向D800-DFFF范圍中的任何代碼點分配實際字符 - 這些代碼點僅在使用時才有意義在替代對。
Hence an individual code point from a surrogate pair does not represent a character, is invalid unless used in a surrogate pair, and is unconditionally invalid in UTF-32 and UTF-8 (if strict conformance to the standard is applied).
因此,來自代理對的單個代碼點不表示字符,除非在代理對中使用,否則是無效的,并且是無條件無效的UTF-32和UTF-8(如果嚴格遵守標(biāo)準(zhǔn))。
字符按照UTF-16進行編碼的規(guī)則是: - 字符的值小于0x10000的用等于該值的16位整數(shù)來表示。 - 字符的值介于0x10000和0x10FFFF之間的,用一個值介于0xD800和0xDBFF(在所謂的高8位區(qū))的16位整數(shù)和值介于0xDC00和0xDFFF(在所謂的低8位區(qū))的16位整數(shù)來表示。 - 字符的值大于0x10FFFF不能按照UTF-16進行編碼。注意:在0xD800和0xDFFF間的值是特別為UTF-16預(yù)留,所以不應(yīng)該將任何字符的值指定為這個區(qū)間內(nèi)的數(shù)值。
D800-DB7F High Surrogates 高位替代 895
DB80-DBFF High Private Use Surrogates 高位專用替代 127
DC00-DFFF Low Surrogates 低位替代 1023
高位替代就是指這個范圍的碼位是兩個WORD的UTF-16編碼的第一個WORD。低位替代就是指這個范圍的碼位是兩個WORD的UTF-16編碼的第二個WORD。那么,高位專用替代是什么意思?我們來解答這個問題,順便看看怎么由UTF-16編碼推導(dǎo)Unicode編碼。
如果一個字符的UTF-16編碼的第一個WORD在0xDB80到0xDBFF之間,那么它的Unicode編碼在什么范圍內(nèi)?我們知道第二個WORD的取值范圍是0xDC00-0xDFFF,所以這個字符的UTF-16編碼范圍應(yīng)該是0xDB80 0xDC00到0xDBFF 0xDFFF。我們將這個范圍寫成二進制:
1101101110000000 11011100 00000000 - 1101101111111111 1101111111111111
按照編碼的相反步驟,取出高低WORD的后10位,并拼在一起,得到
1110 0000 0000 0000 0000 - 1111 1111 1111 1111 1111
即0xe0000-0xfffff,按照編碼的相反步驟再加上0x10000,得到0xf0000-0x10ffff。這就是UTF-16編碼的第一個WORD在0xdb80到0xdbff之間的Unicode編碼范圍,即平面15和平面16。因為Unicode標(biāo)準(zhǔn)將平面15和平面16都作為專用區(qū),所以0xDB80到0xDBFF之間的保留碼位被稱作高位專用替代。
————————————————
版權(quán)聲明:本文為CSDN博主「Lobxxx」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/xinbaobaoer/article/details/56290210