最近發(fā)現(xiàn)一直對java默認(rèn)的utf-8編碼存在疑問,于是我想從控制臺打印"一"入手,挖掘一下整個過程。如下圖
成都創(chuàng)新互聯(lián)公司咨詢電話:13518219792,為您提供成都網(wǎng)站建設(shè)網(wǎng)頁設(shè)計及定制高端網(wǎng)站建設(shè)服務(wù),成都創(chuàng)新互聯(lián)公司網(wǎng)頁制作領(lǐng)域10多年,包括三輪攪拌車等多個領(lǐng)域擁有多年的網(wǎng)站設(shè)計經(jīng)驗,選擇成都創(chuàng)新互聯(lián)公司,為網(wǎng)站錦上添花。開始debug,utf-8在編碼漢字的時候用的三個字節(jié),下圖也能看出來。三個值為負(fù)數(shù)是因為每個字節(jié)對應(yīng)的10進(jìn)制數(shù)都大于128而越界了
我們再把負(fù)數(shù)轉(zhuǎn)換成對應(yīng)的正的10進(jìn)制數(shù),具體方法就是跟0xff作“&”運算,
分別得到228(11100100),184(1011 1000),128 (1000 0000)。
utf-8編碼漢字三個字節(jié)的格式就是1110XXXX 10XXXXXX 10 XXXXXX ,取出下劃線部分就是漢字“一”對應(yīng)的真實二進(jìn)制數(shù)字100111000000000(15位)
計算下
再看下19968對應(yīng)的字符
驗證也是對的,證明了我的結(jié)論。
幾個關(guān)鍵要點:
1、utf-8編碼漢字是三個字節(jié),格式是前面說的那個格式,為什么要定義成這樣的格式其實很好理解,編碼后成這樣,解碼的時候直接取出x號對應(yīng)的部分,直接就能找到整個字節(jié)序真正包含要傳輸表達(dá)的字符
2、byte數(shù)組在存放大于128的數(shù)字時會越界,然后就是負(fù)數(shù)存放了,后面得到具體的數(shù)值就是“&0xff”得到對應(yīng)的正數(shù)
拿-127舉例
-127的二進(jìn)制為:11111111(由于是負(fù)數(shù),所以符號位為1),
存儲到計算機需要進(jìn)行補碼,正數(shù)補碼后為原本的數(shù)組,負(fù)數(shù)補碼為除符號位外,都進(jìn)行取反操作,補碼后,二進(jìn)制為:10000000,
轉(zhuǎn)換int需要補齊32位,所以變?yōu)?1111111 11111111 11111111 10000000,(正數(shù)補0,負(fù)數(shù)補1)
由于byte不需要高24位,所以需要 & 0xff進(jìn)行清零,變?yōu)?0000000 00000000 00000000 ?10000000,進(jìn)行+1操作,二進(jìn)制為:00000000 00000000 00000000 10000001,
這里10000001并不是負(fù)數(shù),由于要轉(zhuǎn)換為int類型,int為32位,所以最高位為0,
轉(zhuǎn)換為十進(jìn)制后,就是129。
后續(xù):理解了編碼的原理就能理解亂碼的問題了,如果一段文本經(jīng)utf-8編碼的二進(jìn)制流后經(jīng)其他編碼解碼時,由于解碼的格式跟utf-8不同,每次取的二進(jìn)制長度都不一樣,整個二進(jìn)制流就會亂掉,于是就亂碼了。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧