中文字元編碼的相互轉換(一)

2021-06-21 09:39:13 字數 2558 閱讀 3828

作為程式設計師,在日常的工作中總會遇到編碼的知識。尤其是在前後臺互動的過程中,字元編碼如影隨行。如果多個平台的字元編碼不一致,需要相互轉化的話,很有必要了解一下編碼的工作原理。

網上有太多關於編碼的知識了,在此我盡量按照我對編碼的理解描述的簡單易懂。

1,ascii碼

在計算機內部,所有的資訊最終都表示為乙個二進位制的字串。每乙個二進位制位是乙個bit,有0和1兩種狀態。8個bit構成乙個位元組,也就是byte。這就是bit和byte的區別。

0和1各代表乙個狀態,乙個byte有8個bit,總共可以表示2的8次方=256個狀態。若是每個狀態對應乙個符號,乙個byte可以表示256個符號,也就是從0000000到11111111。

在上個世紀60年代,美國制定了一套字元編碼,對英語字元與二進位制位之間的關係,做了統一規定。這就是大名鼎鼎的ascii碼了,一直沿用至今。此後雖然出現了各種各樣的編碼,但基本上都是相容ascii碼的。

但ascii碼一共只規定了128個字元的編碼,比如空格"space"是32(二進位制00100000),大寫的字母a是65(二進位制01000001)。這128個符號(包括32個不能列印出來的控制符號),只占用了乙個位元組的後面7位,最前面的1位統一規定為0。

2,gb2312

英語用128個符號編碼就夠了,但是用來表示其他語言,128個符號是不夠的。我們就以中文做例子,中國的漢字有10萬左右,即使是常用字也有六七千,必須得用多個位元組來表示。

最先誕生的是gb2312編碼。其編碼結構不用特別了解清楚,感興趣的可以去網上搜尋專門的文件。我們只需要明白以下幾點:

1)該編碼可以表示大概7000左右個字元。其中有中文及一些常見的拉丁字母等。基本可以覆蓋我們日常打字使用。

2)該編碼完全相容ascii碼,計算機去讀的時候首先判斷最高位,如果是0,那麼這個字元只占用乙個位元組,表示的內容跟ascii碼表示的一樣。如果該字元最高位是1,那麼該位元組連同下乙個位元組表示乙個中文漢字。所以平常咱們常說的英文乙個位元組,中文兩個位元組其實是從這裡來的。

3,gbk

兩個位元組最多可以表示的字元數是 2的16次方=65536,如果要求首位必須是1,那麼最多可以表示 32768 個字元,但是gb2312 只用了其中的7000左右的字元。這顯然是沒有做到物盡其用,而且如果有些特殊的中文,gb2312根本表示不了。所以gbk就應運而生了。

gbk 就盡量將能用到的狀態都表示成中文字元了,當然最終還是有些狀態沒辦法用(具體可以自行查詢文件),最終可以表示23940個字元,其中有21003是漢字。

gbk是完全相容gb2312的,所以gbk的應用是很廣泛的,而且從windows95開始,windows的中文版預設中文支援就是gbk編碼。

4,unicode

gbk基本解決了中文編碼問題,但另外乙個大問題隨之而來,那就是國際化。咱們按照此方式來表示簡體中文,正體中文怎麼表示?日本和南韓他們的文字也沒法弄。當然他們也利用最高位來做文章,發明了big5等相容ascii碼的編碼格式,但是這幾種編碼之間是並不相容的。一段gbk編碼的檔案在台灣友人的電腦裡開啟就是亂碼了。

這時候,unicode就誕生了。

完全弄明白unicode的細節是非常困難的,我們也是明白以下幾點就夠了:

1)unicode編碼是給世界上所有的符號都分配了乙個碼。gbk最多也只能表示3萬多的漢字,康熙字典裡面的大部分漢字都沒法用gbk表示,但是unicode就能,它可以表示這個星球上所有的符號。

2)unicode有ucs-2和ucs-4兩種編碼,2和4都是代表位元組的意思,也就是說前者用兩個位元組表示,後者用4個位元組表示。所以,ucs-2的表示範圍是65536個字元,而ucs-4則可以表示超過22億個字元,我想這真的是可以表示所有的字元了。其實日常使用我們用的只是ucs-2,一般說的unicode編碼也是只它。它包含了所有的簡體中文,現用的正體中文,火星文,以及其他國家的現用文字。古籍中的文字就得去ucs-4中去找了。

5,utf-8

很遺憾,unicode並不是完美的。不完美的地方主要有兩點:

1)不相容ascii碼。因為unicode是用兩個位元組表示,ascii碼範圍內的字元都被擴充成了兩個位元組,前面又補了8個0。所以,如果你的電腦只支援unicode編碼的話,所有的英文資料全都沒法閱讀了。

2)占用的儲存變大,如果涉及到傳輸,所耗費的流量也會變大。中文的表現一般,英文表現最明顯。純英文文字所消耗的儲存比以前增大了一倍。

這個時候就出現了諸如utf-8等實現方式。這裡我們只討論utf-8,因為它是使用最廣泛的。它彌補了unicode的缺陷,所以一誕生就風靡全球了。utf-8主要有以下幾個優點。

1)utf-8與unicode是一一對應的。所以utf-8是國際化的編碼方式。

2)utf-8是針對unicode的可變長度字元編碼,最短乙個位元組,最長3個位元組,1個位元組表示的就是ascii碼,所以utf-8是完全相容ascii碼的。

3)正是因為utf-8的變長實現,解決了unicode的儲存多的問題。可能有朋友要問了,utf-8最多需要用3個位元組表示,而unicode只需要兩個,怎麼能說uft-8會省儲存呢?因為目前英文是最通用的語言,大部分字元都是ascii碼。

但utf-8並不是一點缺點也沒有,因為變長表示,所以一段utf-8編碼沒法一下子算出有多少個字元。而這一點能力對於以上幾種編碼格式來說是輕而易舉的。所以當今世界上沒有最完美的字元編碼,只有最合適某個場景的編碼。

Java 中文字元編碼

public class test for int i 0 i string類的不帶引數的getbytes 方法會以程式所執行平台的預設編碼方式為準來進行轉換,在不同環境下可能會有不同的結果,因此建議使用指定編碼方式的getbytes string charsetname 方法。public sta...

PHP Unicode編碼相互轉換

str 原始中文字串 encoding 原始字串的編碼,預設utf 8 prefix 編碼後的字首,預設 postfix 編碼後的字尾,預設 function unicode encode str,encoding utf 8 prefix postfix else foreach arr cont...

c 中文與GBK編碼值相互轉換

最近專案中用到要把中文和gbk編碼值相互轉換,功能是把16進製制的gbk編碼值轉換成字串輸出,把字串轉換成十六進製制輸出。比較簡單,在這裡做個記錄,方便以後檢視。開發環境vs2015,c 檢視字元編碼 簡體中文 gbk內碼查詢 include include include using namesp...