1. 程式人生 > >跟燕十八學習PHP-第三十天-MySQL字元亂碼解決

跟燕十八學習PHP-第三十天-MySQL字元亂碼解決





/** 
燕十八 公益PHP培訓 
課堂地址:YY頻道88354001 
學習社群:www.zixue.it 
**/






編碼問題:




計算機裡,只有010101 
而人的世界裡,有文字,有圖片,有聲音....




01 ---> 文字對應起來




人為的約定


65->A
66->B
...
...




0100 0001 [A,65]


2進位制編碼 到 字元的對映,就是字符集.






看自己的鍵盤


A-Z 
a-z
0-9
+-*/&^% 


不超過127個.


美國人在造計算機的時候,就沒考慮到,還有其他的字元.


















1111 1111 
0000 0000  256種值,


1個位元組8個位 就足夠了.


事實上,7個位就夠了,因為7個位,可能表示128種變化.




ascii
0-127來表示


0xxx xxxx ,最高位始終是0




到了中國


常用漢字3000多,生僻漢字不用說.




1個位元組,夠不夠?
答:不夠,任你變,不過256種.


思考:用2個位元組來表示
[][]


0000 0000 0000 0000
1111 1111 1111 1111
0-> 65535,6萬多種組合,夠用了.


GB2312字符集 


[202 197] 假如代表 中
[69 197] 代表 ? 
[200 101]


202 197 69 197 200 101....


69和197整個理解,還是單理解成E


歧義: 就是因為單位元組的小於127的值,正好是ascii的值.
如果就嚴格的2位元組繫結,理解為中文,
則gb2312不能識別英文了.




問: 如何相容ascii,又能雙位元組表示中文?


ascii 0-127


0xxxx xxxx


乾脆 gb2312完全不佔用0-127.






我的組合來自於
[129-255][129-255] 




130 140 97 95 134 198
看:能幾個中文,幾個英文?




但是,中文的組合數,也少了.
只能組合10000+,
事實上,GB2312只能容納6000多字






GBK還是雙位元組,如何擴充容量?
答:


GBK的第2低,低位,不再侷限於129-255了,<127的也能用


140 35 65 179 82
 問:幾個中文,幾個英文?


總結: 碰到>128的,就再往後找一位元組.2位元組理解成中文.
繼續找,


找到>128的,就帶個家屬. ,127的,就單身






中國 GBK 
[137][134] ->中


到了日本呢?


[137][134]-> す ふに 呆


jis




ANSI 代表本地字符集


在中文操作 GBK
在日本  JIS




中文-->
中華人民頤和園


拿到日本-->讀-->亂?




解決了多位元組之後, 又相來一個問題----世界各國的字符集,相容問題.






終極大招: Unicode






unicode是一個世界通用的碼錶


00000000 0000 0041 -->A
......................中
..................->す




全世界的範圍的字元,統一分配一個標號.


這樣,不會亂了.




unicode用4個位元組,來編號


2^32 ,40多億, 天文數字. 足夠用了




但我們常用的,集中在 前65535個標號裡.
2個位元組就夠了.


但是,unicode只負責分配編號用的,而且都用4個位元組來分配編號.


你負責編號,


我負責在不改變你編號的基礎上,簡化位元組.


0000 0000 0000 0000 0000 0000 0000 0041 ->A


0000 0041 ->A




把高位浪費的0值,用一定的規則捨棄.




形成的編碼方式 ,  






unicode與utf-8的關係


就像原檔案  --> 壓縮檔案的關係.


問: 給定unicode字元---> utf-8的二進位制值?






 utf-8的二進位制值?--->unicode字元






utf8佔幾個位元組呢?


不可能定長,否則壓縮還有什麼意義?


變長,如何確定字元的邊界?




23 179 234 123




如何擷取utf8(各國語言都有),無亂碼?
答: 從頭開始,取1個位元組.
通過位運算,計算連續的1的個數.


如為0,則擷取1個位元組
如為N,則擷取N個位元組






從容量上來看


GB2312 < GBK < UTF-8








問: GBK中文經常在java中,被轉為utf-8?
答:怎麼轉的?


GBK 也是和unicode有對應關係的.


GBK->unicode->utf-8




亂碼是如何形成的?






utf-8-->轉成gb2312,
容量大    容量小
丟失了位元組?




聯結器的特性: 連線客戶端與伺服器


客戶端的字元先發給聯結器


聯結器選擇一種編碼將其轉換,臨時儲存


再次轉換成 伺服器需要的編碼,並存儲在伺服器




燕十八老師太幽默了, 昨天的視訊如下:


http://www.tudou.com/programs/view/5xOUBkB_T4Q/