什么是字符編碼
計算機要想工作必須通電,即用‘電’驅使計算機干活,也就是說‘電’的特性決定了計算機的特性。電的特性即高低電平(人類從邏輯上將二進制數1對應高電平,二進制數0對應低電平),關於磁盤的磁特性也是同樣的道理。結論:計算機只認識數字。
很明顯,我們平時在使用計算機時,用的都是人類能讀懂的字符(用高級語言編程的結果也無非是在文件內寫了一堆字符),如何能讓計算機讀懂人類的字符?
必須經過一個過程:
-
字符 --------》翻譯過程 -------》數字
總而言之,字符編碼是將人類的字符編碼成計算機能識別的數字,這種轉換必須遵循一套固定的標准,該標准無非是人類字符與數字的對應關系,稱之為字符編碼表。
字符編碼發展史與分類
計算機由美國人發明,最早的字符編碼為ASCII,只規定了英文字母數字和一些特殊字符與數字的對應關系。最多只能用 8 位來表示(一個字節),即:2**8 = 256,所以,ASCII碼最多只能表示 256 個符號。
當然我們編程語言都用英文沒問題,ASCII夠用,但是在處理數據時,不同的國家有不同的語言,中國人會加入中文,日本人會在自己的程序中加入日文,韓國人也是。
但是要表示中文,ASCII是不可能表達完的(連小學生都認識兩千多個漢字),解決方法只有一個,就是一個字節用>8位2進制代表,位數越多,代表的變化就多,這樣,就可以盡可能多的表達出不同的漢字。
所以中國人規定了自己的標准編碼gb2312,規定了包含中文在內的字符與數字的對應關系。
日本人規定了自己的Shift_JIS編碼;韓國人規定了自己的Euc-kr編碼
這時候問題出現了,精通18國語言的小周同學謙虛的用8國語言寫了一篇文檔,那么這篇文檔,按照哪國的標准,都會出現亂碼(因為此刻的各種標准都只是規定了自己國家的文字在內的字符跟數字的對應關系,如果單純采用一種國家的編碼格式,那么其余國家語言的文字在解析時就會出現亂碼)。所以迫切需要一個世界的標准(能包含全世界的語言)於是Unicode應運而生。
ascii用1個字節(8位二進制)代表一個字符;Unicode常用2個字節(16位二進制)代表一個字符,生僻字需要用4個字節。
例:字母x,用ascii表示是十進制的120,二進制0111 1000。
漢字中已經超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。
字母x,用Unicode表示二進制0000 0000 0111 1000,所以Unicode兼容ascii,也兼容萬國,是世界的標准。
這時候亂碼問題消失了,所有的文檔我們都使用但是新問題出現了,如果我們的文檔通篇都是英文,你用Unicode會比ascii耗費多一倍的空間,在存儲和傳輸上十分的低效。
本着節約的精神,往硬盤存入數據時,把Unicode編碼轉化為“可變長編碼”的UTF-8(Unicode Transformation Format-8)編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節,常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符才會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間:
字符 | ASCII | Unicode | UTF-8 |
---|---|---|---|
A | 01000001 | 00000000 01000001 | 01000001 |
中 | x | 01001110 00101101 | 11100100 10111000 10101101 |
從上面的表格還可以發現,UTF-8編碼有一個額外的好處,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續工作。
所以現狀是內存使用Unicode編碼,硬盤使用UTF-8編碼.
內存為什么不用UTF-8呢?
出現這個問題的原因是歷史遺留問題,不同國家的硬盤中還躺了其他國家的代碼,各個國家的代碼的二進制還需要運行在計算機上使用,因此內存中必須使用Unicode的編碼.
內存中還使用Unicode編碼,是因為歷史遺留問題造成的,但是因為現在寫代碼使用的都是UTF-8代碼,所以以后內存中的代碼都將變成UTF-8代碼,並且以前遺留的各個國家的代碼都將被淘汰,所以未來內存中使用的編碼也將使用UTF-8編碼替代Unicode編碼。
亂碼問題分析
-
文件從內存刷到硬盤的操作簡稱存文件
-
文件從硬盤讀到內存的操作簡稱讀文件
亂碼的兩種情況:
-
亂碼一:存文件時選擇了錯誤的編碼格式
如:Mysql數據庫沒配置編碼格式時默認使用拉丁編碼,你往數據庫插入漢字就會亂碼,數據就丟失了(這是因為不同編碼之間轉換時,如果遇到轉換失敗的字節,會使用類似 ? 或 � 來代替,這樣你再轉換回去的時候,就不是原來的字節了)
亂碼二:讀文件時亂碼
如:存文件時用utf-8編碼,而讀文件時選擇了錯誤的解碼方式,比如gbk,則在讀階段發生亂碼,這時數據不會丟失選擇正確的編碼方式打開即可
-