字符編碼到底是什麼?

計算機只認識01,要想讓計算機認識“A”這個字符,需要用某種方法將這個字符映射爲01二進制

字符與01之間的映射就稱爲編碼。

映射集就是編碼表。

那怎麼制定一個編碼表,來表示這種映射關係呢?

ASCII碼出現了

一、ASCII 碼

上個世紀60年代,美國製定了一套字符編碼,對英語字符與二進制位之間的關係,做了統一規定。這被稱爲 ASCII 碼,一直沿用至今。

ASCII 碼一共規定了128個字符的編碼,比如空格SPACE是32(二進制00100000),大寫的字母A是65(二進制01000001)。這128個符號(包括32個不能打印出來的控制符號),只佔用了一個字節的後面7位,最前面的一位統一規定爲0

美國這邊ASCII碼當然可以,但處理中文顯然不夠,漢字數量多達10萬左右,一個字節只能表示256種符號,肯定是不夠的,必須使用多個字節表達一個符號。

所以中國定製了GB2312編碼,使用兩個字節表示一個漢字,理論上最多可以表示 256 x 256 = 65536 個符號。

日本、韓國、歐洲也各制定了一套自己的編碼。

但是有個問題

如果我現在有一個需求,就是一個網站可以隨意切換國家語言。

這麼一搞的話,N個國家就得N個網站頁面。爲了避免這種低效率的工作,推出一套統一的編碼標準勢在必行。

Unicode應運而生。

Unicode編碼

Unicode把所有語言都統一到一套編碼裏,這樣只要切換編碼而不是重寫頁面,也不會有亂碼問題了

Unicode標準在不斷的發展,但最常用的是用兩個字節表示一個字符(如果要用到非常偏僻的字符,就需要4個字節)。

Unicode 是一個很大的集合,現在的規模可以容納100多萬個符號。

現代操作系統和大多數編程語言都直接支持Unicode。

Unicode和ASCII的區別:2字節(通常情況) PK 1字節

字母A用ASCII編碼是十進制的65,二進制的01000001;

字符0用ASCII編碼是十進制的48,二進制的00110000,注意字符'0'和整數0是不同的;

漢字‘中’已經超出了ASCII編碼的範圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。

你可以猜測,如果把ASCII編碼的A用Unicode編碼,只需要在前面補0就可以,因此,A的Unicode編碼是00000000 01000001。

新的問題又出現了

1)如何才能區別 Unicode 和 ASCII ?計算機怎麼知道三個字節表示一個符號,而不是分別表示三個符號呢?

2)如果文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不划算。

所以,又出現一種能把Unicode編碼轉化爲“可變長編碼”的UTF-8編碼。

UTF-8

UTF-8 就是在互聯網上使用最廣的一種 Unicode 的實現方式。其他實現方式還包括 UTF-16(字符用兩個字節或四個字節表示)和 UTF-32(字符用四個字節表示),不過在互聯網上基本不用。重複一遍,這裏的關係是,UTF-8 是 Unicode 的實現方式之一。

UTF-8 最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~6個字節表示一個符號,根據不同的符號而變化字節長度。常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符纔會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間:

UTF-8 的編碼規則很簡單,只有二條:

1)對於單字節的符號,字節的第一位設爲0,後面7位爲這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。

2)對於n字節的符號(n > 1),第一個字節的前n位都設爲1,第n + 1位設爲0,後面字節的前兩位一律設爲10。剩下的沒有提及的二進制位,全部爲這個符號的 Unicode 碼。

下表總結了編碼規則,字母x表示可用編碼的位。

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

跟據上表,解讀 UTF-8 編碼非常簡單。如果一個字節的第一位是0,則這個字節單獨就是一個字符;如果第一位是1,則連續有多少個1,就表示當前字符佔用多少個字節。

下面,還是以漢字爲例,演示如何實現 UTF-8 編碼。

的 Unicode 是4E25100111000100101),根據上表,可以發現4E25處在第三行的範圍內(0000 0800 - 0000 FFFF),因此的 UTF-8 編碼需要三個字節,即格式是1110xxxx 10xxxxxx 10xxxxxx。然後,從的最後一個二進制位開始,依次從後向前填入格式中的x,多出的位補0。這樣就得到了,的 UTF-8 編碼是11100100 10111000 10100101,轉換成十六進制就是E4B8A5。

 

總結

搞清楚了ASCII、Unicode和UTF-8的關係,我們就可以總結一下現在計算機系統通用的字符編碼工作方式:

在計算機內存中,統一使用Unicode編碼,當需要保存到硬盤或者需要傳輸的時候,就轉換爲UTF-8編碼。

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

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