1. 程式人生 > >字元編碼簡介

字元編碼簡介

1.問題:亂碼

     在linux上,經常遇到這樣的問題:新安轉過的系統,經常無法顯示漢字(亂碼);使用Vim或者gedit等編輯器的時候經常把漢字顯示位亂碼。使用python等語言來處理網頁檔案,經常會出現亂碼的情況。所有的這些問題都和字元編碼有關

2.為何會出現亂碼?

    計算機中儲存的資訊都是用二進位制數表示的;而我們在螢幕上看到的英文、漢字等字元是二進位制數轉換之後的結果。通俗的說,按照何種規則將字元儲存在計算機中。例如ASCII採用7位編碼,a被編號為65,所有字元編碼最高位都為0;此時如果計算機讀取到某位元組是是65,就顯示“a”;如果某個位元組儲存的是ox1000,0000,而我們仍然採用ASCII進行解碼,此時就會無法解碼或者出現亂碼。這就是說,編碼要於解碼對應才不會出現亂碼。

3.常用字元編碼

    常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。計算機要準確的處理各種字符集文字,需要進行字元編碼,以便計算機能夠識別和儲存各種文字。 

3.1 ASCII編碼

    美國資訊交換標準程式碼是一種用於資訊交換的美國標準程式碼。7位字符集廣泛用於代表標準美國鍵盤上的字元或符號。通過將這些字元使用的值標準化,ASCII允許計算機和計算機程式交換資訊。ASCII字符集是與ANSI字符集中的前面128個(0-127)字元相同。

    編碼內容:常用英文字元/控制字元。

    字符集數量:128

    編碼特徵:每個編碼長度均為一個位元組,高位是0

    優缺點:字符集數量過小,對歐洲常用字元支援比較弱。

    為了解決字符集數量太少的問題,衍生出EASCII字符集,仍然是一個位元組,但是高位為1.

3.2 GB2312編碼

    為了解決漢字編碼問題,GB2312規定:一個小於127的字元的意義與原來相同,但兩個大於127的字元連在一起時,就表示一個漢字,前面的一個位元組(他稱之為高位元組)從0xA1用到 0xF7,後面一個位元組(低位元組)從0xA1到0xFE,這樣我們就可以組合出大約7000多個簡體漢字了。在這些編碼裡,還把數學符號、羅馬希臘的 字母、日文的假名們都編進去了,連在ASCII裡本來就有的數字、標點、字母都統統重新編了兩個位元組長的編碼,這就是常說的"全形"字元,而原來在127號以下的那些就叫"半形"字元了。

    特點:2位元組編碼,最高位都為1(如果為0,將按照ASCII解碼)

    評介:解決了漢字編碼問題,但是簡體字與生僻字的問題沒有解決。

3.3 GB18030編碼

    簡介:GB 18030,全稱:國家標準GB 18030-2005《資訊科技 中文編碼字符集》,是中華人民共和國現時最新的內碼字集。

    特點:

  • UTF-8相同,採用多位元組編碼,每個字可以由1個、2個或4個位元組組成。
  • 編碼空間龐大,最多可定義161萬個字元。
  • 支援中國國內少數民族的文字,不需要動用造字區。
  • 漢字收錄範圍包含繁體漢字以及日韓漢字

3.4 BIG5字符集

      Big5,又稱為大五碼五大碼,是使用繁體中文(正體中文)社群中最常用的電腦漢字字符集標準,共收錄13,060個漢字。中文碼分為內碼交換碼兩類,Big5屬中文內碼,知名的中文交換碼有CCCIICNS11643。Big5雖普及於臺灣香港澳門等繁體中文通行區,但長期以來並非當地的國家標準,而只是業界標準倚天中文系統Windows等主要系統的字符集都是以Big5為基準,但廠商又各自增加不同的造字與造字區,派生成多種不同版本。2003年,Big5被收錄到CNS11643中文標準交換碼的附錄當中,取得了較正式的地位。這個最新版本被稱為Big5-2003。

4.UNIcode

    為了適合當地語言和字元,設計和實現類似GB2312/GBK/GB18030/BIG5的編碼方案。這樣各搞一套,在本地使用沒有問題,一旦出現在網路中,由於不相容,互相訪問就出現了亂碼現象。

   舉個例子:

   在西方國家的EASCII之中,如果一個8b的數字用來表示一個字元,當最高位是1的時候,它表示一個拉丁字元等其他特殊字元;但是中文編碼GB2312卻規定,兩個8b的字元,如果高位為1,那麼它表示一個漢子。具體而言,“1111,0111;1111,0111”使用EASCII表示兩個約等號,使用GB2312解碼卻表示一個漢子:也就是說,同樣的儲存,用不同的編碼方案來解碼,得到的結果不同。另外一個方面,同樣對於“約等於號”,GB2312給它的編碼是A1D006:對於同樣的字元,不同的字符集有不同的編碼。

    為了解決這個問題,一個偉大的創想產生了——Unicode。Unicode編碼系統為表達任意語言的任意字元而設計。可以想象,如果有一種編碼,將世界上所有的符號都納入其中。每一個符號都給予一個獨一無二的編碼,那麼亂碼問題就會消失。這就是Unicode,就像它的名字都表示的,這是一種所有符號的編碼。它使用4位元組的數字來表達每個字母、符號,或者表意文字(ideograph)。每個數字代表唯一的至少在某種語言中使用的符號。(並不是所有的數字都用上了,但是總數已經超過了65535,所以2個位元組的數字是不夠用的。)被幾種語言共用的字元通常使用相同的數字來編碼,除非存在一個在理的語源學(etymological)理由使不這樣做。不考慮這種情況的話,每個字元對應一個數字,每個數字對應一個字元。即不存在二義性。不再需要記錄"模式"了。U+0041總是代表'A',即使這種語言沒有'A'這個字元。

Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三種字元編碼方案。

Unicode當然是一個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,U+4E25表示漢字"嚴"。

5.UNICODE的問題

需要注意的是,Unicode只是一個符號集,它只規定了符號的二進位制程式碼,卻沒有規定這個二進位制程式碼應該如何儲存。

比如,漢字"嚴"的unicode是十六進位制數4E25,轉換成二進位制數足足有15位(100111000100101),也就是說這個符號的表示至少需要2個位元組。表示其他更大的符號,可能需要3個位元組或者4個位元組,甚至更多。

這裡就有兩個嚴重的問題,第一個問題是,如何才能區別Unicode和ASCII?計算機怎麼知道三個位元組表示一個符號,而不是分別表示三個符號呢?第二個問題是,我們已經知道,英文字母只用一個位元組表示就夠了,如果Unicode統一規定,每個符號用三個或四個位元組表示,那麼每個英文字母前都必然有二到三個位元組是0,這對於儲存來說是極大的浪費,文字檔案的大小會因此大出二三倍,這是無法接受的。

它們造成的結果是:1)出現了Unicode的多種儲存方式,也就是說有許多種不同的二進位制格式,可以用來表示Unicode。2)Unicode在很長一段時間內無法推廣,直到網際網路的出現。

5.UTF-8

UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字元編碼定長碼),也是一種字首碼。它可以用來表示Unicode標準中的任何字元,且其編碼中的第一個位元組仍與ASCII相容,這使得原來處理ASCII字元的軟體無須或只須做少部份修改,即可繼續使用。因此,它逐漸成為電子郵件網頁及其他儲存或傳送文字的應用中,優先採用的編碼。網際網路工程工作小組(IETF)要求所有網際網路協議都必須支援UTF-8編碼。

下表總結了編碼規則,字母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是4E25(100111000100101),根據上表,可以發現4E25處在第三行的範圍內(0000 0800-0000 FFFF),因此"嚴"的UTF-8編碼需要三個位元組,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。然後,從"嚴"的最後一個二進位制位開始,依次從後向前填入格式中的x,多出的位補0。這樣就得到了,"嚴"的UTF-8編碼是"11100100 10111000 10100101",轉換成十六進位制就是E4B8A5。


參考文獻:

相關推薦

中文字元編碼簡介 GB2312/GBK/GB18030/BIG5

2 GBKGB2312-80僅收漢字6763個,這大大少於現有漢字,隨著時間推移及漢字文化的不斷延伸推廣,有些原來很少用的字,現在變成了常用字,例如:朱鎔基的“鎔”字,未收入GB2312-80,現在大陸的報業出刊只得使用(金+容)、(金容)、(左金右容)等來表示,形式不一而同,這使得表示、儲存、輸入、處理都非

字元編碼簡介

1.問題:亂碼      在linux上,經常遇到這樣的問題:新安轉過的系統,經常無法顯示漢字(亂碼);使用Vim或者gedit等編輯器的時候經常把漢字顯示位亂碼。使用python等語言來處理網頁檔案,經常會出現亂碼的情況。所有的這些問題都和字元編碼有關 2.為何會出現亂碼

字符集與字元編碼簡介(轉)

我們知道,計算機只能識別諸如0101這樣的二進位制數,於是人們必須以二進位制資料與計算機進行互動,或者先將人類使用的字元按一定規則轉換為二進位制數。 那什麼是字元呢?在計算機領域,我們把諸如文字、標點符號、圖形符號、數字等統稱為字元。而由字元組成的集合則成為字符集,字符集由於

常用字元編碼簡介

字元編碼要注意 1. 字元編碼儲存位數 2. 中文字元編碼相容性 3. Unicode 字元編碼的 BOM 字元編碼位數參考下表 中文字元編碼相容性 常用簡體中文編碼:GB2312、GBK、GB18030。 GB2312 相

Java字元編碼知識簡介 .

1、基本資訊 摘要:在Java應用程式特別是Web應用中,經常遇到字元的編碼問題。為了防止出現亂碼,首先需要了解字元編碼的基本概念以及Java是如何處理字元編碼的,這樣就可以有目的地在輸入/輸出環節中增加必要的轉碼。本文將分以下幾部分介紹: 1.   什麼是字符集?什麼是編碼? 2.   常用字符集有哪些?

圖片編碼簡介

參考文獻 nsdata jpg 二進制流 undefined ffd str int -1 數據在網絡中是以二進制流的形式傳播的,那麽我們該如何把那些1和0解析成我們需要的數據格式呢?當文件都使用二進制流作為傳輸時,需要制定一套規範,用來區分該文件到底是什麽類型的。 文件頭

day03_09 編碼部分歷史及文件編碼簡介

最大的 課件 big pri alt int color gb2 lex 詳細課件:http://www.cnblogs.com/alex3714/articles/5465198.html 字符編碼 支持中文的第一張表就是GB2312 1980 gb2312 6700+

JavaSE-21 字符編碼簡介

change 其他 範圍 utf gpo sta 一個 sci 電腦 ASCII ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和

編碼部分歷史及python文件編碼簡介

python 編碼 UTF-8 = unicode的擴展集,可變長的字符編碼集 ascii --> gb2312 --> gbk1.0 -->gb18030 ascii --> unicode --> utf-8 Python2.x == asci

Python3字元編碼

原文地址 編碼 字串是一種資料型別,但是,字串比較特殊的是還有一個編碼問題。 因為計算機只能處理數字,如果要處理文字,就必須先把文字轉換為數字才能處理。最早的計算機在設計時採用8個位元(bit)作為一個位元組(byte),所以,一個位元組能表示的最大的整數就是255(

第二篇 Python資料型別、字元編碼、檔案處理

一、引子     1、什麼是資料?         x=10,10是我們要儲存的資料     2、為何資料要分不同的型別    

linux中修改mysql的字元編碼方式

當發現navicat中建立的資料庫編碼和表編碼都是utf8,但通過web端或者其他方式儲存的資料是亂碼,這時就要考慮是否是安裝mysql時,沒有配置mysql伺服器的編碼格式。 檢查mysql伺服器的編碼格式 1)登入mysql客戶端:mysql -uroot -p 2)查詢

二進位制與字元編碼

計算機能識別的只有1和0,也就是二進位制,而1和0可以表達出全世界的所有文字和語言符號。 我們人類採用的是十進位制算術法,主要原因是因為我們有10個手指頭。如果我們只有2個手指頭的話,我們就會用二進位制計數,就會逢二進一,那可能是這樣計數的:1,10,11,20,21,30,31,40。。。。。。其中1代表

PHP介面:字元編碼和資料格式由請求方定義

根據一個老專案寫介面,發現專案檔案編碼為gbk,而且資料庫也是gbk,由於程式碼量巨大,不可能更改專案程式碼以及資料庫的字元編碼。 請求介面的也有好多個: 老客戶一直用的gbk字元編碼的資料來請求的,原來寫的介面收到的資料格式為xml, 新客戶要求用utf-8格式,接收資料為json。 看了

node 讀取cav 異常編碼簡介

var iconv = require('iconv-lite'); var fileStr = fs.readFileSync(‘xxx.csv’, { encoding: 'binary' }); var buf = new Buffer(fileStr,

Python2與Python3的字元編碼與解碼

轉載於:https://www.jianshu.com/p/19c74e76ee0a 編碼與解碼 編碼(encode):在Unicode中,每一個字元都有一個唯一的數字表示,那麼將Unicode字串轉換為特定字元編碼(ASCII、UTF-8、GBK)對應的位元組串的過程和規則就是編碼。

Java工具類-轉換字元編碼

package common; /** *字串處理公用類 */ public class DealString { /** * 轉換字元編碼 由“iso-8859-1”西文轉換為簡體中文 */ public static String toGb(

Java工具類-設定字元編碼

package common; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; i

【轉載】字元編碼中ASCII、Unicode和UTF-8的區別

1. ASCII碼 我們知道,在計算機內部,所有的資訊最終都表示為一個二進位制的字串。每一個二進位制位(bit)有0和1兩種狀態,因此八個二進位制位就可以組合出256種狀態,這被稱為一個位元組(byte)。也就是說,一個位元組一共可以用來表示256種不同的狀態,每一個狀態對應一個符

第一模組-:(第2章)資料型別、字元編碼、檔案操作

1、漢字點陣碼是一種用黑白兩色點陣來表示漢字字形的編碼。一個8*8點陣字模的儲存容量為? 1、1位元組(Byte)有8位元(Bit) 2、黑白兩色每個點佔用1Bit 3、8×8點陣需要64個Bit 4、因為1Byte有8Bit,所以64Bit/8Bit/Byte = 8Byte 答案是B:8位