unicode字符集和utf-8編碼

字符集和編碼

我們在實際開發中, 經常需要處理文字資訊, 組成文字的單元我們稱之為字元 計算機只能處理0和1, 不能直接處理這些字元, 比如說對字元的讀取和儲存

為了解決這個問題, 我們可以建立一個數字與字元的關聯關係, 比如說使用97 -> a, 98 -> b, 99 -> c。。依據數字可以查詢對應字元, 依據字元可以查詢對應數字

這樣我們需要處理字元的時候, 就可以先查詢這個對映, 找到字元對應的數字, 然後把這個數字轉換成二進位制儲存即可, 讀取的時候亦然

字符集: 為每一個字元分配一個唯一的數字, 這個數字可以稱之為碼點

編碼規則: 把碼點轉換為位元組序列的規則

新的問題

計算機最早是美國發明的, 所以一開始只需要處理英文的字元就可以了, 也就是ascii字符集。 後來計算機越來越普及, 更多的國家開始使用計算機, 這個時候就需要處理更多的字元, 比如說中文字元, 日韓字元。。。由於ascii字符集不支援, 所以各個國家也產生了許多支援更多字元的字符集, 比如說支援簡體中文的gb2312字符集, 支援簡體中文、繁體中文和日韓字元的gbk字符集。。。

多個字符集的問題:

維護起來十分複雜, 對於相同的字元, 多個字符集可能重複維護

不同字符集對同一個字元分配的碼點可能不一樣, 這樣就導致編碼和解碼必須使用相同的字符集, 不然可能會出現亂碼

unicode字符集和utf-8編碼

unicode字符集

為了解決上述多個字符集的問題, 我們需要一個維護所有字元, 統一的字符集, 我們稱之為unicode字符集。 uniocde14。0版本, 一共收錄了144697個字元

unicode字符集和utf-8編碼

unicode字符集

編碼規則

unicode解決了字符集統一的問題, 接下來還需要制定相應的編碼規則

定長編碼

最簡單粗暴的編碼規則, 所有碼點都使用相同長度的位元組來表示, 比如說現在已知的字元數量大概14W多, 可以使用三個位元組來表示(0 ~ 16777216)

優點: 編碼簡單

缺點: 不夠節約空間, 只需要使用一個位元組和兩個位元組表示的字元也使用了三個位元組來表示

變長編碼

針對不同範圍的碼點, 使用不同長度的位元組序列來表示 utf-8就是一種變長編碼

unicode字符集和utf-8編碼

utf-8編碼規則

位元組

格式

實際編碼位

碼點範圍

1位元組

0xxxxxxx

7

0 ~ 127

2位元組

110xxxxx 10xxxxxx

11

128 ~ 2047

3位元組

1110xxxx 10xxxxxx 10xxxxxx

16

2048 ~ 65535

4位元組

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

21

65536 ~ 2097151

utf-8編碼規則, 是一種字首編碼規則, 每一個位元組都是由標誌位 + 實際編碼位組成, 第一個開始位元組的高位1的個數表示這個編碼佔用了幾個位元組, 只佔用一個位元組的時候比較特殊, 使用0作為高位標誌位

為什麼佔用多個位元組時, 除了第一個開始位元組外, 後續的位元組也需要10作為字首標誌位?

後續位元組使用10作為字首標誌位, 標誌這個位元組不能作為一個開始位元組, 也是為了解決和開始位元組的字首標誌位衝突, 實際上是為了解碼服務

這樣做可以把開始位元組和非開始的位元組區分開, 可以對utf-8編碼進行校驗, 如果一個開始位元組後的後續位元組數和開始位元組字首標誌位中的位元組數不符合, 那麼校驗失敗

utf編碼和解碼圖示:

unicode字符集和utf-8編碼

utf-8編碼/解碼