Unicode與UTF 8的區別

2021-09-30 00:17:22 字數 3567 閱讀 4845

ascii 編碼

在計算機的世界裡,資訊的表示方式只有 0 和 1,但是我們人類資訊表示的方式卻與之大不相同,很多時候是用語言文字、影象、聲音等傳遞資訊的。

怎樣將其轉化為二進位制儲存到計算機中,這個過程我們稱之為編碼。更廣義地講就是把資訊從一種形式轉化為另一種形式的過程。 

乙個二進位制有兩種狀態:」0」 狀態 和 「1」狀態,那麼它就可以代表兩種不同的東西,想賦予它什麼含義,就賦予什麼含義,比如:「0」 代表 「吃過了」, 「1」代表 「還沒吃」。這樣就相當於把現實生活中的資訊編碼成二進位制數字了,並且這個例子中是一位二進位制數字,那麼2位二進位制數可以代表四種情況(2^2)分別是 00、01、10、11,那麼7種是2^7=128。

計算機中每八個二進位制位組成了乙個位元組(byte),計算機儲存的最小單位就是位元組,位元組如下圖所示 :

早期人們用8位二進位制來編碼英文本母(最前面的一位是0),也就是說,將英文本母和一些常用的字元和這128中二進位制0、1串一一對應起來,比如:大寫字母「a」所對應的二進位制位「01000001」,轉換為十六進製制為41。

在美國,這128是夠了,但是其他國家不夠,他們的字元和英文是有出入的,比如在法語中在字母上有注音符號,如 é 。所以各個國家就決定把位元組中最前面未使用的那乙個位拿來使用,原來的128種狀態就變成了256種狀態,比如é就被編碼成130(二進位制的10000010)。

為了保持與ascii碼的相容性,一般最高位為0時和原來的ascii碼相同,最高位為1的時候,各個國家自己給後面的位(1*** ***x)賦予他們國家的字元意義。

但是這樣一來又有問題出現了,不同國家對新增的128個數字賦予了不同的含義,比如說130在法語中代表了é,但是在希伯來語中卻代表了字母gimel(這不是希伯來字母,只是讀音翻譯成英文的形式)具體的希伯來字母gimel看下圖 

所以這就成了不同國家有不同國家的編碼方式,所以如果給你一串二進位制數,想要解碼,就必須知道它的編碼方式,不然就會出現我們有時候看到的亂碼 。

unicode碼

unicode為世界上所有字元都分配了乙個唯一的數字編號,這個編號範圍從 0x000000 到 0x10ffff(十六進製制),有110多萬,每個字元都有乙個唯一的unicode編號,這個編號一般寫成16進製制,在前面加上u+。例如:「馬」的unicode是u+9a6c。

unicode就相當於一張表,建立了字元與編號之間的聯絡

它是一種規定,unicode本身只規定了每個字元的數字編號是多少,並沒有規定這個編號如何儲存。

有的人會說了,那我可以直接把unicode編號直接轉換成二進位制進行儲存,是的,你可以,但是這個就需要人為的規定了,而unicode並沒有說這樣弄,因為除了這種直接轉換成二進位制的方案外,還有其他方案,主要有utf-8,utf-16,utf-32。(utf-8、utf-16、utf-32……都是 unicode編碼 的一種實現。)

1、utf-32 

這個就是字元所對應編號的整數二進位制形式,四個位元組,這個就是直接轉換。 比如:馬的unicode為:u+9a6c,那麼直接轉化為二進位制,它的表示就為:1001 1010 0110 1100。

注意:轉換成二進位制後計算機儲存的問題。計算機在儲存器中排列位元組有兩種方式:大端法和小端法,大端法就是將高位位元組放到底位址處,比如0x1234, 計算機用兩個位元組儲存,乙個是高位位元組0x12,乙個是低位位元組0x34,它的儲存方式為下:

utf-32用四個位元組表示,處理單元為四個位元組(一次拿到四個位元組進行處理),如果不分大小端的話,那麼就會出現解讀錯誤,比如我們一次要處理四個位元組 12 34 56 78,這四個位元組是表示0x12 34 56 78還是表示0x78 56 34 12 ,不同的解釋最終表示的值不一樣。

我們可以根據他們高低位元組的儲存位置來判斷他們所代表的含義,所以在編碼方式中有 utf-32be 和 utf-32le ,分別對應大端和小端,來正確地解釋多個位元組(這裡是四個位元組)的含義。

2、utf-16 

utf-16使用變長位元組表示 

① 對於編號在u+0000到u+ffff的字元(常用字符集),直接用兩個位元組表示。 

② 編號在 u+10000到u+10ffff之間的字元,需要用四個位元組表示。

同樣,utf-16 也有位元組的順序問題(大小端),所以就有utf-16be表示大端,utf-16le表示小端。

3、utf-8 

utf-8就是使用變長位元組表示,顧名思義,就是使用的位元組數可變,這個變化是根據 unicode 編號的大小有關,編號小的使用的位元組就少,編號大的使用的位元組就多。使用的位元組個數從1到4個不等。

utf-8的編碼規則:

① 對於單位元組的符號,位元組的第一位設為0,後面的7位為這個符號的unicode碼,因此對於英文本母,utf-8編碼和ascii碼是相同的。 

② 對於n位元組的符號(n>1),第乙個位元組的前n位都設為1,第n+1位設為0,後面位元組的前兩位一律設為10,剩下的沒有提及的二進位制位,全部為這個符號的unicode碼 。

舉個例子:比如說乙個字元的unicode編碼是130,顯然按照utf-8的規則乙個位元組是表示不了它(因為如果是乙個位元組的話前面的一位必須是0),所以需要兩個位元組(n = 2)。

根據規則,第乙個位元組的前 2 位都設為1,第3(2+1)位設為0,則第乙個位元組為:110x ***x,後面位元組的前兩位一律設為10,後面只剩下乙個位元組,所以後面的位元組為:10xx ***x。所以它的格式為110***xx 10****** 。

unicode編號範圍與對應的utf-8二進位制格式 :

對於乙個具體的unicode編號,具體進行utf-8的編碼的方法:

首先找到該unicode編號所在的編號範圍,進而可以找到與之對應的二進位制格式,然後將該unicode編號轉化為二進位制數(去掉高位的0),最後將該二進位制數從右向左依次填入二進位制格式的x中,如果還有x未填,則設為0 。

比如:「馬」的unicode編號是:0x9a6c,整數編號是39532,對應第三個範圍(2048 - 65535),其格式為:1110***x 10****** 10******,39532 對應的二進位制是 1001 1010 0110 1100,將二進位制填入進入就為: 11101001 10101001 10101100 。

由於utf-8的處理單元為乙個位元組(也就是一次處理乙個位元組),所以處理器在處理的時候就不需要考慮這乙個位元組的儲存是在高位還是在低位,直接拿到這個位元組進行處理就行了,因為大小端是針對大於乙個位元組的數的儲存問題而言的。

Unicode與utf 8的區別

在初學程式設計時,總是對編碼的一些概念不太理解,其中unicode與utf 8出現次數最多,以下是我個人的理解 unicode 是乙個很龐大的字符集,涵蓋了世界上所有語言的字元,ascii也是乙個字符集,包含了128個英文本元 utf 8 是一種編碼規則,具體是一套編碼單位為8位的可變長編碼。在un...

Unicode和utf 8的區別

很久以前儲存的,別人寫的但是很明了 很久很久以前,有一群人,他們決定用8個可以開合的電晶體來組合成不同的狀態,以表示世界上的萬物。他們看到8個開關狀態是好的,於是他們把這稱為 位元組 再後來,他們又做了一些可以處理這些位元組的機器,機器開動了,可以用位元組來組合出很多狀態,狀態開始變來變去。他們看到...

utf 8和Unicode的區別

utf 8和unicode到底有什麼區別?是儲存方式不同?編碼方式不同?它們看起來似乎很相似,但是實際上他們並不是同乙個層次的概念 要想先講清楚他們的區別,首先應該講講unicode的來由。中國人不高興了,特麼我們漢字有幾萬個,常用的就有幾千個,沒有兩個位元組根本交不了貨。於是勤勞勇敢的中國人民就破...