每個開發人員都應知道的字元編碼知識

轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。

部分原文出處://www.freecodecamp.org/news/everything-you-need-to-know-about-encoding/

這篇文章里,我會向大家簡要的介紹編碼相關的歷史,同時還會通過介紹部分電腦科學理論的基礎來幫助更好的理解編碼知識。

編碼介紹及歷史

我們都知道電腦只能理解二進位數據暨0和1,二進位是電腦語言,這是因為電腦在設計之初是由八個電晶體通過開合來表示數據的,於是這八位二進位數據被稱為「位元組」,一個位元組根據八位的不同組合共有256種不同的結果。

在電腦啟用之初,由於只在美國本土使用,所以開發者通過256個編碼制定了ASCII標準,ASCII是將二進位字元對應到大小寫字母、數字和常用符號的映射關係表,表如下:

 

 

我們可以看到,這張表裡只用到了128就能完整表示出所有英語文字的方案了,而128-255位被定義為了擴展字符集,留作日後用來擴展使用,例如用來表示如:邊框、圓角、西文等字元,以下是第一批IBM電腦使用的ASCII的128-255編碼映射關係。

 

 

但隨著電腦的不斷普及,中國和其他的一些國家也開始使用電腦,為了能在電腦上使用自己的文字, 很多國家選擇在127-255擴展定義自己的文字。

我們中國也一樣擴展了自己的映射表,但我們的常用漢字數量還是遠遠大於這個閾值的儲存能力,於是我們定義在中文字元編碼格式下,兩個位元組表示一個漢字。於是在當時各個國家都有自己一套獨特的擴展編碼標準,以至於導致電腦在當時顯示不同國家的字元時經常會出現亂碼。

類似下面這樣

 

 

Unicode的統一

互聯網是將世界各地電腦連接起來的途徑,如果能通過一套標準為每種語言中的每個字元都設定統一且唯一對應的編碼,那麼世界上所有的文字都能正常顯示出來,而不用為了顯示某種文字而頻繁切換codepage。

���當然���如果就是���想顯示֎֏0590成這樣׃ׅׄ׆ׇ除外֐��。

於是ISO國際組織於1994年正式推出了Unicode標準(又稱萬國碼、統一碼)。之所以能統一,是因為Unicode規定了,所有字元統一由兩個位元組來表示,也就是16位。原先的英文字元、數字和半形符號雖然原先在ASCII中只用8位就能表現,但需要擴充為16位的話必須在高位補0, 如下示例:

1 – 00000001 – 00000000 00000001

可以看到,通過增長位數來擴展支援更多的語種這樣的方式很不錯,但在純英文環境下由於沒有用的補零高位會導致文本佔用大量的存儲空間,而這一情況在互聯網時代的到來變得更加明顯。

於是為了解決英文Unicode在網路傳輸時帶來的低效問題,UTF協議也隨之而來。

Unicode 轉換協議 (UTF)

UTF是我們對Unicode碼點進行編碼的一種方式。UTF編碼是由Unicode標準定義的,能夠對我們需要的每一個Unicode碼點進行編碼。

但是UTF標準有不同的類型。它們分為UTF-8、UTF-16和UTF-32,而其中在互聯網中最常用的就是UTF-8,在HTML5中也被置頂位新文檔的默認編碼。

下圖中你可以看到,從2012年開始,UTF-8相較其他字符集的受歡迎度越來越高。

 

 

 

 

什麼是UTF-8,它的工作原理是什麼?

UTF-8是一種可變長的編碼方式,理論上可達6個位元組,但已現行文字和符號看,4個位元組是已經足夠了。

UTF-8以 8位(即 1個位元組)為單元對原始Unicode碼進行編碼,規定:多位元組碼(2個位元組以上)以轉換後第1個位元組起頭的連續「1」的數目(這些連續「1」稱為標記位),表示轉換成幾個位元組:「110」連續兩個「1」,表示轉換結果為2個位元組,「1110」表示3個位元組,而「11110」則表示4個位元組……跟隨在標記位之後的「0」,其作用是分隔標記位和字元碼位。第2~第4個位元組的起頭兩個位固定設置為「10」,也作為標記,剩下的6個位才做為字元碼位使用。這樣,2位元組UTF-8碼剩下11個字元碼位,可用以轉換0080~07FF的原始字元碼,3位元組剩下16個字元碼位,可用以轉換0800~FFFF的原始字元碼,由此類推。編碼方式的模板如下:

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個位元組,歐洲(拉丁),希伯來語和阿拉伯語用2個位元組表示。中文,日文,韓文和其他亞洲字元使用3個位元組。你可能發現了,原本為了解決佔用過長的問題,但實際編碼後中文長度變為了3位元組,如果你的客戶都是中國用戶,使用GBK能部分提高網頁內文本的傳輸效率。

編碼聲明方式

看起來正確聲明編碼類型很重要,那麼,我們該如何指定編碼呢?

只需在<head>中的meta聲明使用的字符集即可,如下:

<html lang="en">
<head>
  <meta charset="utf-8">
</head>

除了以上方式外,我們還可以從HTTP請求/響應的Content-Type表頭中聲明。

最後總結

以上就是關於編碼的一些簡單的介紹,除了列舉出的編碼外,還有很多其他更多類型的編碼,如果大家對其他的內容有補充,歡迎通過留言告訴我。