一、Unicode編碼
1 UTF-8 -16 -32編碼和Unicode編碼
Unicode編碼是一種計算機字符編碼標准,其實個人認為叫字符集更為准確;而我們熟悉的UTF-8 UTF-16 UTF-32是Unicode的具體實現(怎么存儲在計算機)。
1)Unicode編碼規范制定標准:
把世界上所有能出現的字符,都為其分配一個數字來表示,比如,數字U+7F57被分配給了漢字中的"羅"字。Unicode編碼的標准里字符數量一直實在新增(包括一些稀有字符,當然emoji表情字符也屬於unicode編碼哈哈),19年3月剛發布了Unicode12.0版本,比之前的版本新增了一些字符,現在在標准中的字符一共有137929個,而Unicode編碼目前規划了U+0000至U+10FFFF為unicode編碼(以世界上字符的數量應該是很久不會考慮擴展的),算一下目前還剩下976183(1114112-137929)個代碼點,這976183個代碼點是規划在unicode中的數字,但是還沒被分配對應的字符。
2)UTF-8編碼:
UTF-8可以說是當前互聯網最常用的編碼格式了,它基於Unicode字符集進行編碼設計。它最大的特點是變長字節的編碼設計,一個字符最長4個字節,最少1個字節,大部分的中文字符占3個字節。
編碼規則如下:
1.用一個字節表示的字符,第一位設為 0,后面的 7 位對應這個字符的 Unicode 碼點。由於這128個字符的unicode完全對照ASCII碼,可以說完全向下兼容ASCII碼。即ASCII編碼的文件可以用UTF-8打開而不亂碼;
2.用一個字節以上表示的字符,假設是N個字節表示這個字符:則該字符第一個字節的前N位都為1,第N+1位為0,剩下的N-1個字節的前兩位都設為10,剩下沒有主動設值的位置則使用這個字符的Unicode二進制代碼點從低位到高位填充,不夠用0補足。
編碼對照表如下:
| Unicode字符集范圍(十六進制) | UTF-8編碼(二進制) |
| 0000 0000 - 0000 007F | 0xxxxxxx |
| 0000 0080 - 0000 07FF | 110xxxxx 10xxxxxx |
| 0000 0800 - 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
| 0001 0000 - 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
結合編碼規則和編碼對照表,講解漢字“羅”是如何編碼和解碼的:
編碼(encode): 字符“羅”所對應的unicode代碼點由以上規則轉化為UTF-8所對應的二進制數字,則稱為編碼。可以理解為使字符成為代碼的意思,而解碼就是代碼成為字符。
首先“羅”對應了unicode中的U+7F57,對應編碼表中第三行,也就是用3個字節來表示的字符,把7F57的二進制111 1111 0101 0111從低位對應補足到1110xxxx 10xxxxxx 10xxxxxx(從低位) 如下圖所示:
最后成為11100111 10111101 10010111即十六進制E7BD97。

解碼(decode): UTF-8所對應的二進制數字由以上規則轉化為unicode碼再對應到具體字符,則稱為編碼。
如11100111 10111101 10010111這段二進制編碼,第一個字節是111,對應編碼對照表則這段編碼表示的字符由3個字節組成,用1110xxxx 10xxxxxx 10xxxxxx規則剔除出x對應的數為111 1111 0101 0111,即7F57,該數字對應unicode字符集中的字符“羅”。
3)UTF-32編碼:
同理和UTF-8基於unicode字符集。UTF-32編碼為固定長度4個字節。因為unicode范圍為00FFFF-10FFFF,4個字節表示的范圍為00000000-FFFFFFFF,能直接表示所有unicode編碼,不需要進行轉換編碼轉換。以空間換時間。
3)UTF-16編碼:
UTF-16以2或者4個字節編碼表示unicode字符:
unicode字符集中,000000-00FFFF表示的字符,在UTF-16中用2字節直接編碼表示,不需要編碼轉換,這點和UTF-32一樣(這里有點需要說明一下, U+D800 到 U+DFFF 是一個空段,即這些碼點不對應任何字符,4字節需要用到)
unicode字符集中,010000-10FFFF表示的字符,在UTF-16中用4字節編碼表示,但是需要進行編碼轉換。比如010000-10FFFF中的某個字符X的uicode編碼為AAAA AAAA AABB BBBB BBBB,分為高10位和低10位,高10位加上高位代理位D8(110110),低10位加上低位代理位DF(110111),即組成字符X的UTF-16編碼110110AAAAAAAAAAA 110111BBBBBBBBBB。
二、java中的char類型
java中char類型是2個字節長度,一個char在java中稱作一個代碼單元,而unicode的字符編碼叫做代碼點。
也就是說utf-16編碼中的0000-FFFF的范圍可以用一個char表示,10000-10FFFF就需要用兩個char來表示。
