標籤:二進位 int nbsp 軟體 顯示 修改 字元編碼 用兩個 問題
1、字元編碼的發展曆程
①、ASCII 碼
因為電腦只認識數字,所以我們在電腦裡面的一切資料都是以數字來表示,因為英文字元有限,所以規定使用的位元組的最高位是 0,每一個位元組都是以 0-127 之間的數字來表示。比如 A 對應 65,a 對應 97。這便是 美國標準資訊交換碼,ASCII
String str = new String("Aa");byte[] strASCII = str.getBytes("ASCII");System.out.println(Arrays.toString(strASCII));//[65, 97]
②、GB2312 碼
隨著電腦在全球的普及,很多國家和地區都把自己的字元引入了電腦,比如漢字。此時發現一個位元組能表示的數字範圍太小,不能包含所有的中文漢字。那麼就規定使用兩個位元組來表示一個漢字。
規定:原有的 ASCII 字元的編碼保持不變,仍然使用一個位元組表示,為了區別一個中文字元與兩個 ASCII 碼字元相區別。中文字元的每個位元組最高位規定為 1(即中文的二進位是負數),這便是 GB2312 編碼
String str = new String("Aa帥鍋");byte[] strASCII = str.getBytes("GB2312");System.out.println(Arrays.toString(strASCII));//[65, 97, -53, -89, -71, -8]
③、GBK
由於中國漢字太多,在 GB2312 的基礎上增加了更多的中文字元,這種編碼是 GBK
問題:如果只是在中國,那麼大家都認識漢字,但是如果是別的國家,而該國家的碼錶中是沒有收錄漢字的。那麼電腦在顯示的時候就為亂碼或是別的字元
解決辦法:為瞭解決各個國家因為本地化字元編碼帶來的影響,就把全世界所有的字元統一進行編碼---Unicode 編碼
此時某一個字元在全世界任何地方顯示都是固定的,比如漢字 哥,在任何地方都是以十六進位 54E5 來表示。
Unicode 的字元編碼都佔有兩個位元組
④、UTF-8
是一種針對 Unicode 的可變長度字元編碼,又稱為 萬國碼,是 Unicode 的實現方式之一。編碼中的第一個位元組仍與 ASCII 相容,這使得原來處理 ASCII 字元的軟體無須或只需做少部分修改,即可繼續使用。因此,它逐漸成為電子郵件、網頁及其他儲存或傳送文字的應用中,優先採用的編碼。互連網工程工作小組(IETF)要求所有互連網協議都必須支援 UTF-8 編碼
String str = new String("Aa帥鍋");byte[] strASCII = str.getBytes("UTF-8");System.out.println(Arrays.toString(strASCII));//[65, 97, -27, -72, -123, -23, -108, -123]
儲存字母、數字:無論什麼字元集都佔有 1 個位元組
儲存漢字:GBK 家族佔有 2 個位元組。UTF-8 佔有 3 個位元組
不能使用單位元組的字元集(ASCII/ISO-8859-1)來儲存中文
2、字元的編碼和解碼
資訊在電腦網路中傳輸是以位元組的形式。那麼如何變為位元組?這就是編碼的過程。那麼電腦接收了這個編碼,如何讓使用者認識呢?那必須要將位元組轉換為人所識別的字串形式,這就是解碼的過程。
編碼:將字串轉換為 byte 數組
解碼:把 byte 數群組轉換為 字串
注意:①、編碼格式和解碼格式必須一致,否則亂碼
String str = new String("Aa帥鍋");//編碼操作byte[] strByte = str.getBytes("GBK");System.out.println(Arrays.toString(strByte));//[65, 97, -53, -89, -71, -8]//解碼操作 //注意編碼的字元集和解碼的字元集格式必須一致(是其擴充字元集也可以),否則會亂碼//第一種:編碼格式為 GBK,解碼格式為 ISO-8859-1 那麼就會亂碼String str2 = new String(strByte,"ISO-8859-1");System.out.println(str2); //Aa?§??//第二種:編碼和解碼格式一致String str3 = new String(strByte,"GBK");System.out.println(str3); //Aa帥鍋
②、有時候編碼為和解碼格式一致了,但是還是亂碼,這是因為在資料在傳輸過程中經過伺服器的處理,而這個伺服器可能是外國人編寫的,那麼就會將資料轉換為 別的字元格式設定,那麼你如果還是直接轉為自己想要的格式是會亂碼的。
解決辦法:先擷取經過伺服器之後的資料還原編碼,然後在進行解碼
String str = new String("Aa帥鍋");//編碼操作byte[] strByte = str.getBytes("UTF-8");System.out.println(Arrays.toString(strByte));//[65, 97, -27, -72, -123, -23, -108, -123]//中間經過了伺服器的傳輸,編碼格式轉成了 ISO-8859-1String str2 = new String(strByte,"ISO-8859-1");//解碼操作 ,此時如果直接進行解碼,那麼會亂碼String str3 = new String(str2.getBytes(),"UTF-8");System.out.println(str3); //Aa???????//對於上面的亂碼,我們必須先還原伺服器之前的編碼格式,然後在進行解碼。那麼就不會亂碼byte[] strByte2 = str2.getBytes("ISO-8859-1");String str4 = new String(strByte2,"UTF-8");System.out.println(str4); //Aa帥鍋
Java 字元編碼與解碼