編碼&解碼
計算機的世界都是用數(shù)字表示噪径。所謂的字符編碼柱恤,就將字符轉(zhuǎn)換成一一對應(yīng)的數(shù)字,解碼就是將數(shù)字轉(zhuǎn)換成字符找爱。編碼的方式和解碼的方式不一樣就會亂碼梗顺。
ASCII編碼
計算機最早開端于美帝國,只需要對字母和一些控制字符編碼就行了车摄,所以有了ASCII
編碼寺谤,用一個字節(jié)8位表示字符,能支持256個吮播。
unicode 字符集與UTF-8編碼
后來其他語言國家变屁,也普及了計算機,不夠用了意狠,就需要擴展 ASCII 編碼了粟关。國際組織就設(shè)計了unicode
字符集,希望能容納全世界全部語言文字摄职。
unicode 兼容ASCII誊役,每個字符對應(yīng)的數(shù)字,成為代碼點(codepoint)谷市。如果嚴(yán)格按照unicode的方式(UCS-2用16位)定長存儲蛔垢,那么代碼點值比較小的英文二進制編碼中高位有很多0,浪費空間迫悠,因此就有了變長編碼方式鹏漆,如UTF-8
(8-bit Unicode Transformation Format)、UTF-16(16-bit Unicode Transformation Format) 等创泄。在這些編碼方式中艺玲,字符對應(yīng)的代碼點不變,通過編碼后二進制存儲形式不同鞠抑。
UTF-8 中饭聚,代碼點范圍及對應(yīng)的編碼方式:
//代碼點 :編碼
U+ 0000 ~ U+ 007F: 0XXXXXXX
U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
U+10000 ~ U+10FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
根據(jù)以上規(guī)則,那么“張”字的代碼點為0x5F20搁拙,對應(yīng)第3條秒梳,將代碼點的二進制位從低到高,依次填入“x”的位置箕速,位數(shù)不夠補0酪碘,得到UTF-8編碼為:11101011011110010100000。以下為java中的驗證:
public static void main(String[] args) throws Exception {
String str = "張";
int codePoint = str.codePointAt(0);//
System.out.println(codePoint);//24352
System.out.println(Integer.toHexString(codePoint));//0x5F20
System.out.println(Integer.toBinaryString(codePoint));//101111100100000
byte[] bytes = str.getBytes("UTF-8");
for (byte aByte : bytes) {//111001011011110010100000
System.out.print(Integer.toBinaryString(aByte & 0xFF));
}
}
參考視頻:https://www.ltool.net/characters-to-unicode-charts-in-simplified-chinese.php?unicode=117
查詢unicode 各種字符的所在的范圍:https://www.ltool.net/characters-to-unicode-charts-in-simplified-chinese.php?unicode=117盐茎,發(fā)現(xiàn)易經(jīng)六十四卦符號(U+4DC0->4DFF)兴垦。