字符编码表
一、了解字符編碼表
一:計算機基礎知識
1、程序運行與三大核心硬件(cpu,內存,硬盤)的關系:
任何一個程序都是先存放于硬盤上的,必須先由硬盤讀取到內存,之后cpu去內存中取值然后執行
2、程序運行過程中產生的數據最先放在內存中,計算機內部存取的數據用的都是010101010101的二進制
二、文本編輯器和python解釋器運行原理
python程序運行的三個步驟
python3 D:\a.py
1、先啟動python解釋器
2、解釋器會將a.py的內容當成普通內存從硬盤讀入內存,此時沒有語法意義
3、解釋器會解釋執行剛剛讀入內存的內存,開始識別python語法
任何一個程序都是先存放于硬盤上的,必須先由硬盤讀取到內存,之后cpu去內存中取值然后執行
文本編輯器
1、打開編輯器就打開了啟動了一個進程,是在內存中的,所以,用編輯器編寫的內容也都是存放與內存中的,斷電后數據丟失
2、要想永久保存,需要點擊保存按鈕:編輯器把內存的數據刷到了硬盤上。
3、在我們編寫一個py文件(沒有執行),跟編寫其他文件沒有任何區別,都只是在編寫一堆字符而已。
總結
相同:1、任何的程序要想運行都是先從硬盤讀取到內存
2、文本編輯器和python解釋器都會去硬盤中讀取你想要讀取的內容
不同:1、文本編輯器將文件內容讀取之后僅僅是展示給用戶看
python解釋器會識別語法并解釋執行python代碼
三、什么是字符編碼
計算機所能識別的都是二進制01010101的數字,所以總結計算機只能認識數字
經歷的過程:
字符-----(翻譯過程)-----數字
這個過程實際就是一個字符如何對應一個特定數字的標準,這個標準稱之為字符編碼
四、字符編碼表發展史
python 2.x默認的字符編碼是ASCII,默認的文件編碼也是ASCII。
python 3.x默認的字符編碼是unicode,默認的文件編碼是utf-8。
1、ASCII:美國人發明的最早的只能識別英文字符
特點:采用8bit對應一個英文字符
8bit=》1Bytes
2、GBK:中國人發明的可以識別中文字符串與英文字符
特點:采用16bit對應字符,該字符可以是英文字符、也可以是中文字符
16bit = 》2Bytes
3、shift-JIS日本人發明的可以識別日文和英文字符
Euc-kr韓國人發明的可以識別韓文和英文字符
4、unicode:可以識別萬國字符
特點:2Bytes對應一個字符
在unicode中對于是英文的文本來說,unicode無疑是多了一倍的存儲空間(二進制最終都是以電或者磁的方式存儲到存儲介質中的)
于是產生了UTF-8(可變長,全稱Unicode Transformation Format),對英文字符只用1Bytes表示,對中文字符用3Bytes,對其他生僻字用更多的Bytes去存
總結:內存中統一采用unicode,浪費空間來換取可以轉換成任意編碼(不亂碼),硬盤可以采用各種編碼,如utf-8,保證存放于硬盤或者基于網絡傳輸的數據量很小,提高傳輸效率與穩定性。
字符-----》unicode格式的數字
GBK shiftJIS**
基于目前的現狀,內存中的編碼固定就是unicode,我們唯一可變的就是硬盤的上對應的字符編碼。
1、
英文字符--------------內存:ASCII二進制數--------------->硬盤:ASCII二進制數
中文英文字符--------------內存:GBK二進制數--------------->硬盤:GBK二進制數
日文英文字符--------------內存:shiftJIS二進制數--------------->硬盤:shiftJIS二進制數
韓文英文字符--------------內存:Euc-Kr二進制數--------------->硬盤:Euc-Kr二進制數
2、
中文英文字符------------內存:unicode=gbk====>硬盤:GBK二進制數
日文英文字符------------內存:unicode=shifJIS>硬盤:shiftJIS二進制數
韓文英文字符------------內存:unicode=Euc-Kr=>硬盤:Euc-Kr二進制數
萬國字符----------------內存:unicode=utf-8==>硬盤:utf-8二進制數
3、
萬國字符----------------內存:unicode=utf-8==>硬盤:utf-8二進制數
萬國字符----------------內存:utf-8==========================>硬盤:utf-8二進制數
在讀入內存時,需要將utf-8轉成unicode
所以我們需要明確:內存中用unicode是為了兼容萬國軟件,即便是硬盤中有各國編碼編寫的軟件,unicode也有相對應的映射關系,但在現在的開發中,程序員普遍使用utf-8編碼了。
亂碼問題
無論以什么編碼在內存里顯示字符,存到硬盤上都是二進制,所以編碼不對,程序就會出錯。
1、存的時候亂了:采用的字符編碼表無法識別輸入的字符
存的時候就已經亂了,是無法補救的,取的時候一定也亂了
解決方法:存入硬盤的編碼格式應該用utf-8格式
2、存的時候沒有亂碼:采用的字符編碼表可以識別輸入的字符
但是取的時候亂碼了:采用的字符編碼表與當初存的時候用的不是同一張表
解決方法:存的時候用什么編碼,取的時候一定要用同樣的編碼格式
與運行python程序有關的亂碼問題:
1、保證運行python程序的前兩個階段不亂碼
在python文件的開頭加一行:
#coding:文件存的時候用的編碼格式
python2.x的bytes與python3.x的bytes的區別
Python2將string處理為原生的bytes類型,而不是 unicode。而Python3所有的 string均是unicode類型。
在python2.x中,寫字符串,比如
s = ”學習“
print s
學習
s # 字節類型
‘\xd1\xa7\xcf\xb0’
雖然說打印的是中文學習,但是直接調用變量s時,顯示的卻是一個個16進制表示的二進制字節,我們稱這個為byte類型,即字節類型,它把8個二進制組成一個byte,用16進制表示。
所以說python2.x的字符串其實更應該稱為字符串,通過存儲的方式就能看出來,但是在python2.x中還有一個bytes類型,兩個是否相同呢,回答是肯定的,在python2.x中,bytes==str。
python3.x中,把字符串變成了unicode,文件默認編碼為utf-8。這意味著,只要用python3.x,無論我們的程序以那種語言開發,都可以在全球各國電腦上正常顯示。
python3.x除了把字符串的編碼改成了unicode,還把str和bytes做了明確區分,str就是unicode格式的字符串,而bytes就是單純的二進制。(補充一個問題,在python3.x中,只要把unicode編碼,字符串就會變成了bytes格式,也不直接打印成gbk的字符,我覺得就是想通過這樣的方式明確的告訴你,想在python3.x中看字符串,必須是unicode,其他編碼一律是bytes格式)。
深入中文編碼問題
python3內部使用的是unicode編碼,而外部卻要面對千奇百怪的各種編碼,比如作為中國程序經常要面對的gbk,gb2312,utf8等,那這些編碼是怎么轉換成內部的unicode呢?
首先看一下源代碼文件中使用字符串的情況。源代碼文件作為文本文件就必然是以某種編碼形式存儲代碼的,python2默認源代碼文件是asci編碼,python3默認源代碼文件是utf-8編碼。比如給python2代碼文件中的一個變量賦值:
s1 = ‘a’
print s1
python2認為這個字符’a’就是一個asci編碼的字符,這個文件可以正常執行,并打印出’a’字符。在僅僅使用英文字符的情況下一切正常,但是如果用了中文,比如:
s1 = ‘哈哈’
print s1
這個代碼文件被執行時就會出錯,就是編碼出了問題。python2默認將代碼文件內容當作asci編碼處理,但asci編碼中不存在中文,因此拋出異常。
解決問題之道就是要讓python2解釋器知道文件中使用的是什么編碼形式,對于中文,可以用的常見編碼有utf-8,gbk和gb2312等。只需在代碼文件的最前端添加如下:
# -- coding: utf-8 --
這就是告知python2解釋器,這個文件里的文本是用utf-8編碼的。這樣,python就會依照utf-8的編碼形式解讀其中的字符,然后轉換成unicode編碼內部處理使用。
不過,如果你在Windows控制臺下運行此代碼的話,雖然程序是執行了,但屏幕上打印出的卻不是哈哈字。這是由于python2編碼與控制臺編碼的不一致造成的。Windows下控制臺中的編碼使用的是gbk,而在代碼中使用的utf-8,python2按照utf-8編碼打印到gbk編碼的控制臺下自然就會不一致而不能打印出正確的漢字。
解決辦法一個是將源代碼的編碼也改成gbk,也就是代碼第一行改成:
# -- coding: gbk --
另一種方法是保持源碼文件的utf-8不變,而是在’哈哈’前面加個u字,也就是:
s1=u’哈哈’
print s1
這樣就可以正確打印出’哈哈’字了。這里的這個u表示將后面跟的字符串以unicode格式存儲。python2會根據代碼第一行標稱的utf-8編碼,識別代碼中的漢字’哈哈’,然后轉換成unicode對象。如果我們用type查看一下’哈哈’的數據類型type(‘哈哈’),會得到<type ‘str’>,而type(u’哈哈’),則會得到<type ‘unicode’>。
type(‘哈哈’)
<type ‘str’>
type(u’哈哈’)
<type ‘unicode’>
也就是在字符前面加u就表明這是一個unicode對象,這個字會以unicode格式存在于內存中,而如果不加u,表明這僅僅是一個使用某種編碼的字符串,編碼格式取決于python2對源碼文件編碼的識別,這里就是utf-8。
Python2在向控制臺輸出unicode對象的時候會自動根據輸出環境的編碼進行轉換,但如果輸出的不是unicode對象而是普通字符串,則會直接按照字符串的編碼輸出字符串,從而出現上面的現象。
使用unicode對象的話,除了這樣使用u標記,還可以使用unicode類以及字符串的encode和decode方法。
unicode類的構造函數接受一個字符串參數和一個編碼參數,將字符串封裝為一個unicode,比如在這里,由于我們用的是utf-8編碼,所以unicode中的編碼參數使用’utf-8’,將字符封裝為unicode對象,然后正確輸出到控制臺:
s1=unicode(‘哈’, ‘utf-8′)
print s1
另外,用decode函數也可以將一個普通字符串轉換為unicode對象。很多人都搞不明白python2字符串的decode和encode函數都是什么意思。這里簡要說明一下。
decode函數是將普通字符串按照參數中的編碼格式進行解析,然后生成對應的unicode對象,比如在這里我們代碼用的是utf-8,那么把一個字符串轉換為unicode對象就是如下形式:
s2 = ‘哈哈’.decode(‘utf-8’)
type(s2)
<type ‘unicode’>
這時,s2就是一個存儲了’哈哈’字符串的unicode對象,其實就和unicode(‘哈哈’, ‘utf-8′)以及u’哈哈’是相同的。
encode函數正好就是相反的功能,是將一個unicode對象轉換為參數中編碼格式的普通字符串,比如下面代碼:
復制代碼
s3 = unicode(‘哈哈’, ‘utf-8’).encode(‘utf-8’)
type(s3)
<type ‘str’>
或者:
s3 = ‘哈哈’.decode(‘utf-8’).encode(‘utf-8’)
type(s3)
<type ‘str’>
復制代碼
s3現在又變回了utf-8的’哈哈’。同樣的,也可指定其它編碼格式,但要注意的是,用什么格式編碼,就用什么格式解碼,否則會出現中文亂碼問題。
字符編碼
目前使用的編碼方式有:ASCII碼(一個字節)、Unicode碼(兩個字節)、UTF-8碼(可變長的編碼)。我們已經知道了,字符串也是一種數據類型,但是,字符串比較特殊的是還有一個編碼問題。
因為計算機只能處理數字,如果要處理文本,就必須先把文本轉換為數字才能處理。最早的計算機在設計時采用8個比特(bit)作為一個字節(byte),所以,一個字節能表示的最大的整數就是255(二進制11111111=十進制255),如果要表示更大的整數,就必須用更多的字節。比如兩個字節可以表示的最大整數是65535,4個字節可以表示的最大整數是4294967295。
由于計算機是美國人發明的,因此,最早只有127個字符被編碼到計算機里,也就是大小寫英文字母、數字和一些符號,這個編碼表被稱為ASCII編碼,比如大寫字母A的編碼是65,小寫字母z的編碼是122。但是要處理中文顯然一個字節是不夠的,至少需要兩個字節,而且還不能和ASCII編碼沖突,所以,中國制定了GB2312編碼,用來把中文編進去。可以想得到的是,全世界有上百種語言,日本把日文編到Shift_JIS里,韓國把韓文編到Euc-kr里,各國有各國的標準,就會不可避免地出現沖突,結果就是,在多語言混合的文本中,顯示出來會有亂碼。因此,Unicode應運而生。Unicode把所有語言都統一到一套編碼里,這樣就不會再有亂碼問題了。Unicode標準也在不斷發展,但最常用的是用兩個字節表示一個字符(如果要用到非常偏僻的字符,就需要4個字節)。現代操作系統和大多數編程語言都直接支持Unicode。
現在,捋一捋ASCII編碼和Unicode編碼的區別:ASCII編碼是1個字節,而Unicode編碼通常是2個字節。
字母A用ASCII編碼是十進制的65,二進制的01000001;
字符’0’用ASCII編碼是十進制的48,二進制的00110000,注意字符’0’和整數0是不同的;
漢字中已經超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。
可以猜測,如果把ASCII編碼的A用Unicode編碼,只需要在前面補0就可以,因此,A的Unicode編碼是00000000 01000001。
新的問題又出現了:如果統一成Unicode編碼,亂碼問題從此消失了。但是,如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不劃算。
所以,本著節約的精神,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節,常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符才會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間:
字符 ASCII Unicode UTF-8
A 01000001 00000000 01000001 01000001
中 x 01001110 00101101 11100100 10111000 10101101
UTF-8編碼有一個額外的好處,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續工作。
總結
- 上一篇: 良性计算机病毒对计算有没有危害机系统,1
- 下一篇: 计算机组成SRAM,静态读写存储器(SR