字節、字符、編碼方案的簡單介紹

目錄

一、字節概念

二、字符概念

三、編碼規範(編碼方案)

1.字庫表

2.編碼字符集(常說的字符集)

3.字符編碼(編碼方式)

四、常見編碼規範(編碼方案)介紹

1.ASCII碼

2.GBK

3.Unicode


今天和夥計萌一起寫JSP的時候,應用到了修改編碼,所以自己也總結一下這個原理,參考了很多寫的不錯的文章。

可能很多編程的夥伴萌學到了,tomcat 和 JSP(java server page)

這裏先引出幾個常見的英文:

  1. charset英文釋義就是字符集 ,是服務器把生成的html發佈給客戶端時的編碼,可以任意指定

  2. pageEncoding:JSP文件本身的編碼方式

  3. GBK(GBK即“國標”、“擴展”漢語拼音的首字母): 全稱《漢字內碼擴展規範》

  4. UTF-8:針對Unicode的一種可變長度字符編碼。

一、字節概念

字節(Byte )是計算機用於計量存儲容量的一種計量單位,作爲一個單位來處理的一個二進制數字串,是構成信息的一個小單位。最常用的字節是八位的字節,即八位的二進制數。

比如:11110000(2),這個八位的二進制數在計算機中代表佔用了一個字節。

二、字符概念

字符和字節要區別開,字符指類字形單位或符號: 字母、數字、運算符號、標點符號和其他符號,以及一些功能性符號。

比如: 1 、+ & ?%、我 等都是字符

不同的編碼導致一個字符所佔的內存不同

GBK中一箇中文佔兩個字節(即16位二進制) 而 UTF-8中則佔三個字節(24位二進制)

三、編碼規範(編碼方案)

隨計算機的發展,不同地區語言文字的需要,工程師們希望在計算機中顯示字符,但計算機只能識別0和1組成的的二進制數,於是編碼規範被擴展出來。

例如: ASCII編碼規範,計算機通過規範可以將我們常用的字符和二進制之間相互轉換。

GBK編碼規範,計算機可以通過這套規範,在中文和二進制之間相互轉換。

我們識別字符,計算機識別二進制。

1.字庫表

像我們的大字典一樣,每一頁的第幾行作爲一個地址,對應一個值。

一套編碼規範不一定能包含世界上所有字符,每套編碼規範都有自己的使用場景。而字庫表就存儲了編碼規範中能顯示的所有字符,計算機就是根據二進制數從字庫表中找到字符然後顯示給用戶滴,相當於一個存儲字符的數據庫。

比如: 所有漢字都保存在GBK 編碼規範的字庫表中。所以可以顯示漢字,但法語,俄語並不在其字庫表中,所以GBK不能顯示法語,俄語等不包含在其中的字符。

2.編碼字符集(常說的字符集)

在一個字庫表中,每一個字符都有一個對應的二進制地址,而編碼字符集就是這些地址的集合。

例:在ASCII碼的編碼字符集中,字母A的序號(地址)是65,65的二進制就是01000001。我們可以說編碼字符集就是用來存儲這些二進制數的。而這個二進制數就是編碼字符集中的一個元素,同時它也是字庫表中字母A的地址。我們根據這個地址就可以顯示出字母A。

3.字符編碼(編碼方式)

有了字庫表和編碼字符集的概念,我們就可以直接使用二進制地址來得到字符了。

但直接使用字符對應的二進制地址來顯示文字是十分浪費內存的,Unicode 編碼規範中包括了幾百萬個字符,想要包括幾百萬個不同的字符,起碼需要3個字節的容量,爲了方便將來擴展,Unicode還保留了更多未使用的空間,最多可以存儲4個字節的容量。

如果爲了區分每個字符,00000000 00000000 00000000 00001111這種其實只佔了1個字節的字符,我們要爲他分配4個字節的空間,這就導致一個1G大小的文件,需要4G才能保存,很明顯浪費了不少空間。

於是程序員制定了一套算法來節省空間,而每種不同的算法都被稱作一種編碼方式(下文中爲了便於理解都將使用編碼方式來稱呼字符編碼)。一套編碼規範可以有多種不同的編碼方式,不同的編碼方式有不同的適應場景。

例如:UTF-8就是一種編碼方式,Unicode是一種編碼規範。此外,Unicode還有UTF-16,UTF-32這兩種編碼方式。不同的編碼方式規則不同,節約的空間也不同。

總結:一個較短的二進制數,通過一種編碼方式,轉換成編碼字符集中正常的地址,然後在字庫表中找到一個對應的字符,最終顯示給用戶。

四、常見編碼規範(編碼方案)介紹

1.ASCII碼

(American Standard Code for Information Interchange): 美國信息交換標準代碼。

共包含128個字符即二進制的:00000000~011111111.可以表示阿拉伯數字和大小寫英文字母,以及一些簡單的符號。

2.GBK

GBK全稱《漢字內碼擴展規範》,支持國際標準ISO/IEC10646-1和國家標準GB13000-1中的全部中日韓漢字。GBK字符集中所有字符佔2個字節,不論中文英文都是2個字節。 沒有特殊的編碼方式,習慣稱呼GBK 編碼。

3.Unicode

從以上幾種編碼規範可以看出,各種編碼規範互不兼容,且只能表示自己需要的字符,於是,國際標準化組織(ISO)決定製定一套全世界通用的編碼規範,這就是Unicode。 Unicode包含了全世界所有的字符。Unicode最多可以保存4個字節容量的字符。但是要區分每個字符,每個字符的地址需要4個字節。這是十分浪費存儲空間的,於是,程序員就設計了幾種字符編碼方式,比如:UTF-8,UTF-16,UTF-32。 最廣爲程序員使用的就是UTF-8,UTF-8是一種變長字符編碼,注意:UTF-8不是編碼規範,而是編碼方式。

UTF-8編碼規則如下:

編碼規則表

Unicode 十六進制碼點範圍 UTF-8 二進制
0000 0000 ~ 0000 007F 0xxxxxxx
0000 0080 ~ 0000 07FF 110xxxxx 10xxxxxx
0000 0800 ~ 0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000 ~ 0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
   

如上表所示,對於只需要1個字節的字符,UTF-8採用ASCII碼的編碼方式,最高位補0來表示。

例如:01000001我們就是用01000001來表示,對於一個字節的字符,其實就是直接使用地址表示。

而對於n個字節的字符(n>1),即大於一個字節的字符,採用第一個字節前n位補1。第n+1位填0,後面字節的前兩位一律設爲10。剩下的沒有提及的二進制位,全部爲這個符號的unicode碼。

例如:漢字嚴的Unicode碼是4E25轉換成二進制就是01001110 00100101共15位,根據上表可知使用UTF-8字符編碼後佔3個字節,因此前3位是1,第4位(n+1位)是0,後面兩個字節中每個字節的前兩位都是10,即1110 xxxx 10 xxxxxx 10xxxxxx。填充進去後就變成了1110 0100 10 111000 10 100101共計24位佔3個字節。

由此可見,英文在UTF-8字符編碼後只佔1個字節,中文佔了3個字節。 雖然UTF-8編碼沒有GBK編碼佔的空間小,但他勝在面向全世界,至於使用哪一種編碼還是取決於具體的使用環境。

 

關於英文佔一個字節,中文佔三個字節的驗證:


 import java.io.UnsupportedEncodingException;
 ​
 public class Main {
     public static void main(String[] args) throws UnsupportedEncodingException {
         //英文
         String usa = "x";
         encodeAndDecode(usa);
         //中文
         String chinese="何";
         encodeAndDecode(chinese);
 ​
 ​
     }
     public static  void encodeAndDecode(String init) throws UnsupportedEncodingException {
 ​
         byte[] bts = init.getBytes("UTF-8");
         System.out.print("字符'"+init+"'進行編碼得到的三個字節值:");
         for (byte bt : bts)
             System.out.print(bt+" ");
         System.out.println("\n解碼檢驗******************");
         //解碼
         String init_utf8 = new String(bts,"UTF-8");
         System.out.println(init_utf8+"\n");
     }
 }

運行結果如下 

字符'x'進行編碼得到的三個字節值:120 
解碼檢驗
x

字符'何'進行編碼得到的三個字節值:-28 -67 -107 
解碼檢驗
何

 

 

參考:

  1. https://blog.csdn.net/qq_42068856/article/details/83792174?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
  2. https://www.zhihu.com/question/57461614

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章