天天看點

計算機中的編碼問題

目錄

一. 計算機編碼

二. 計算機編碼分類

1. ASCII編碼

2. GBK編碼

3. UTF-8編碼

三. 計算機系統中的編碼應用

四. 編碼問題

 寫代碼的時候經常會碰到編碼問題,一直以來對這個編碼不是太了解,今天就來學下一下。

  • gbk編碼: 中文占用兩個位元組,英文占用一個位元組。
  • utf-8編碼:中文占用三個位元組,英文占用一個位元組。

一. 計算機編碼

       計算機編碼指電腦内部代表字母或數字的一種記錄資料的方式。

       為什麼會出現編碼?我們知道,計算機中的資料是由電子原件存儲的,而因為工業技術  的限制,電子元件隻能記錄兩種穩定狀态“開”和“關”,用數字來表示,就是0 和1。也就是說,本質上計算機隻能記錄0和1這兩個數字。每個0  或者1,我們稱之為一個bit,是計算機最小的機關。這種隻有0和  1的數字,我們稱之為2進制數字。

       但很明顯,我們需要記錄的東西很多,是以隻有兩個數字肯定不行,于是3個bit共同來表示一位數字,就有了8進制。4個  bit共同來表示一位數字,就有了16  進制

       數字問題解決了,但是,如果想在計算機中存儲一個字元‘a’,卻無法做到。為了解決這個問題,人們就想了一種解決方法:把所有的常用的字元都統一編号,如‘a’的編号就是97,這樣,當我們需要存儲‘a’的時候,不直接存儲‘a’,而是存儲數字97,當拿出來的時候,再把這個97變成‘a ’,這樣就完美解決了這個問題。

       而我們通常所說的“編碼”就是這些字元的編号。所有字元的和其編号對應的表格,我們稱之為“編碼表”。

       常見的編碼表:ASCII編碼,GB2312編碼(簡體中文),GBK,BlG5編碼(繁體中文),utf-8編碼等

二. 計算機編碼分類

1. ASCII編碼

       計算機在建立之初,流行于“西方世界”或者叫“英語國家”,拆開來看,西方世界的語言、文字等等,充其量也就是26個英文字母加上一些符号,即使英文字母分大小寫,也絕不超過128個,每個字元使用一個位元組來表示,足夠了。使用一個位元組來表示一個字元的這種編碼方式,就是最早的:ASCII編碼。 

計算機中的編碼問題

2. GBK編碼

       後來,随着計算機的普及,整個世界都需要使用計算機來存儲資料,如果還使用ASCII編碼肯定不行(無法存儲羅馬字母表以外的字元),而且ASCII編碼所規定的一個位元組表示一個字元的這種規定很明顯無法适用于整個世界(漢字至少也要幾千個吧)。是以,各國都對ASCII編碼進行了擴充,由原來的一個位元組表示一個字元,轉換為多個位元組表示一個字元。 

例如GB系列編碼是我國的國标編碼,用來存儲漢字,分為GB2312,GBK,GB18030,基本都能向前相容,其中GBK是目前最通用的。

3. UTF-8編碼

       當然,如果世界各國都使用自己的編碼,那國家與國家之間的交流就比較麻煩,比如本來在你這裡是贊揚的意思,到了對方那裡,因為編碼不同,解析出來是罵人的意思,這就不行了。是以,為了解決這個問題,由一個名為 Unicode 學術學會的組織,制訂了一套編碼規則-Unicode編碼。該規則支援世界上超過650種語言。是一種世界通用字元規則。

       Unicode把所有語言都統一到一套編碼裡,這樣就不會再有亂碼問題了。Unicode标準也在不斷發展,但最常用的是用兩個位元組表示一個字元(如果要用到非常偏僻的字元,就需要4個位元組)。現代作業系統和大多數程式設計語言都直接支援Unicode。不過他隻規定了字元的編碼,卻沒有規定字元以何種方式存儲或者傳輸。是以UTF系列編碼規定了Unicode編碼的存儲和傳輸方式。

      目前最常用的UTF編碼分為3種,UTF-8,UTF-16和UTF-32,我們知道計算機是以8位為一個位元組來存儲資料的,而UTF-16,UTF-32分别用2位元組和4位元組來表示一個字元,是以這裡就涉及到位元組的存儲順序,是低位在前還是高位在前,這樣,BOM就産生了。

BOM是文本檔案開頭的一個特殊标記,用一組特殊數字來标記文本檔案的位元組序。雖然UTF-8位元組順序是固定的,但為了相容UTF-16和UTF-32也規定了UTF-8的BOM,用于标記UTF-8編碼。不過UTF-8的BOM在不同平台的規定不同,要小心使用。

BOM規定如下:

  • UTF-8 EF BB BF
  • UTF-16(LE) FF FE
  • UTF-16(BE) FE FF
  • UTF-32(LE) FF FE 00 00
  • UTF-32(BE) 00 00 FE FF

UTF-8編碼:如果統一成Unicode編碼,亂碼問題從此消失了。但是,如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不劃算。是以,本着節約的精神,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字元根據不同的數字大小編碼成1-6個位元組,常用的英文字母被編碼成1個位元組,漢字通常是3個位元組,隻有很生僻的字元才會被編碼成4-6個位元組。如果你要傳輸的文本包含大量英文字元,用UTF-8編碼就能節省空間:

計算機中的編碼問題

三. 計算機系統中的編碼應用

       在計算機記憶體中,統一使用Unicode編碼,當需要儲存到硬碟或者需要傳輸的時候,就轉換為UTF-8編碼;用記事本編輯的時候,從檔案讀取的UTF-8字元被轉換為Unicode字元到記憶體裡,編輯完成後,儲存的時候再把Unicode轉換為UTF-8儲存到檔案:

計算機中的編碼問題

浏覽網頁的時候,伺服器會把動态生成的Unicode内容轉換為UTF-8再傳輸到浏覽器:

計算機中的編碼問題

是以你看到很多網頁的源碼上會有類似<meta charset="UTF-8" />的資訊,表示該網頁正是用的UTF-8編碼

四. 編碼問題

       所謂的“編碼問題”,其實就是出現了中文亂碼。為什麼出現這種問題呢? 我們中國人,一般使用的都是中文的作業系統,而中文作業系統預設的編碼格式是GBK。而國際上,為了全世界都能看懂,則一般使用UTF-8編碼。(國際性網站一般都是UTF-8編碼) 

  • GBK編碼,一個漢字一般占用2個位元組。 
  • UTF-8編碼,一個漢字一般占用3個位元組

    因為不同的編碼方式中文占用的位元組數不一樣,是以一個編碼方式用另外一個編碼去進行解析就會出現亂碼的問題。

其實,編碼問題”的出現,無非是我們在解析别人給我們漢字的時候,使用的編碼出錯了,如果我們拿到的是GBK,就使用GBK解析,如果拿到的是UTF-8,就是使用UTF-8解析,這樣不就解決了麼?是以,如果是遇到字元串出現中文亂碼:  

1.把中文亂碼字元串重寫打散,變為位元組。

 2.使用xx構造函數重組字元串

       中文亂碼隻是因為我們在對位元組解析的時候,組裝錯誤了,就類似于玩積木的時候,放錯位置了,但本質的位元組沒有改變。

參考:

1. 傳智播客,https://wenku.baidu.com/view/eef190ca0129bd64783e0912a216147917117edd.html

2. https://www.jb51.net/article/119186.htm

繼續閱讀