00 01 02 03 04 05 06 07 08 0A 0B 0C 0D 0E 0F 10 |
因而按照擴展位,劃分了17個維度,這每一個維度,叫作一個平面
17個平面,編號從 0~16
|
每一個平面 65536個字符 |
17個平面,擴展後總共能夠表示1114112個字符 |
擴展後的範圍爲
U+000000 ~ U+10FFFF
|
聽起來可能有點迷惑,不是知道具體的值了麼?怎麼還不知道如何表示? 好比數字1 他的碼點是1 假如我用兩個字節來存儲,每一個字節的前兩位我當作其餘的標誌位, 設置爲11 那麼可能結果是這樣子的11000000 11000001 顯然,他的值並非1 編碼方式只是能夠保證,你的字符是按照指定的字符集進行編碼的 也就是說若是你告訴我拿出來碼點爲1 的,我會把1100 0000 1100 0001 解析成數字1 可是並不能保證我保存的數據就是他的碼點的真值,0000 0001 ,中間形式是編碼方式說了算的 最直觀的例子就是網絡中報文的傳輸,都會附加本身的頭信息 因此中間傳輸的數據並非跟你發送的數據如出一轍,中間的數據就是編碼形式的存儲 可是,接收端接受解析後,就是跟你發送的數據同樣的,這就好像是你的字符 |
UTF-8 是變長
UTF-32 是定長
UTF-16介於他們之間 2個字節或者4個字節
|
UTF-16編碼以16位無符號整數爲單位 |
咱們把Unicode編碼記做U 編碼規則以下
若是U<0x010000, 也就是0x000000 ~ 0x00FFFF
U的UTF-16編碼, 就是U對應的16位無符號整數
|
若是U≥0x010000 也就是0x010000 ~ 0x10FFFF 咱們先計算下 U'=U-0x010000 能夠得出來 U' 範圍是 0x000000 ~ 0x0FFFFF 顯然, U'的最大值爲0xFFFFF 也就是最多20個1 也就是能夠被寫成20個二進制位 既然是20個二進制位,那麼咱們是否是能夠把它拆分紅兩組呢? 每組10個二進制位 00 0000 0000 它能表示的範圍是2的10次方=1024個 BMP是2個字節,16位, 很顯然,若是把U' 拆分紅兩組,每組10個二進制位的話 每個都可以保存到2個字節內 因此Unicode標準規定:基本多語言平面內,U+D800..U+DFFF的值不對應於任何字符,爲代理區 ,其中又分爲高代理區和低代理區 U+D800 加上10個二進制位的數值的最大值,能夠獲得高代理區的範圍 U+D800 --->1101 10 00 0000 0000 + 0000 00 11 1111 1111 = 1101 1011 1111 1111 = 0xDBFF 下一個就是0xDBFF +1 = 0xDC00,因此低代理區從0xDC00 開始 0xDC00 加上10個二進制位的數值的最大值,能夠獲得低代理區的範圍 0xDC00----> 1101 1100 0000 0000 + 0000 00 11 1111 1111 = 1101111111111111 = 0xDFFF |
高代理區範圍 U+D800 ~0xDBFF 低代理區範圍 0xDC00 ~ 0xDFFF 代理區間是U+D800....U+DFFF |
因此UTF-16的編碼方式就是 先計算 U'=U-0x010000 而後將U'寫成二進制形式:yyyy yyyy yyxx xxxx xxxx 而後分別計算高位代理和低位代理 U+D800 --->1101 10 00 0000 0000 + 0000 00 yy yyyy yyyy = 1101 10 yy yyyy yyyy 0xDC00----> 1101 1100 0000 0000 + 0000 00 xx xxxx xxxx = 1101 11xx xxxx xxxx |
再精簡下步驟 1. 先計算 U'=U-0x010000 2. 而後將U'寫成二進制形式:yyyy yyyy yyxx xxxx xxxx 3.兩個值爲 1101 10 yy yyyy yyyy / 1101 11xx xxxx xxxx |
以前咱們提到過,Unicode中的一個字符的值,被稱之爲一個碼點
顯然,一個碼點,可能被一個代碼單元存儲,也可能被兩個連續的代碼單元存儲
|
在內存中0x01020304的存儲方式
內存地址 4000 4001 4002 4003
BE 01 02 03 04
LE 04 03 02 01
|