第一種:ASCII碼
ASCII(American Standard Code for Information Interchange,美國信息交換標准代碼)是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。它是現今最通用的單字節編碼系統,並等同於國際標准ISO/IEC 646。如下圖所示:
由於計算機是美國人發明的,因此,最早只有127個字母被編碼到計算機里,也就是大小寫英文字母、數字和一些符號,這個編碼表被稱為ASCII
編碼,比如大寫字母 A
的編碼是65
,小寫字母 a
的編碼是97
。后128個稱為擴展ASCII碼。
每一位0或者1所占的空間單位為bit(比特),這是計算機中最小的表示單位,每8個bit組成一個字符,這是計算機中最小的存儲單位。
常見換算單位:
bit 位,計算機中最小的表示單位
8bit = 1bytes 字節,最小的存儲單位,1bytes縮寫為1B
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB
第二種:GBK 和 GB2312
對於我們來說能在計算機中顯示中文字符是至關重要的,然而ASCII表里連一個偏旁部首也沒有。所以我們還需要一張關於中文和數字對應的關系表。一個字節只能最多表示256個字符,要處理中文顯然一個字節是不夠的,所以我們需要采用兩個字節來表示,而且還不能和ASCII編碼沖突,所以,中國制定了GB2312編碼,用來把中文編進去。
第三種:Unicode
但如以來,就會出現一個問題,各個國家都一套自己的編碼,就不可避免會有沖突,這是該怎么辦呢?
因此,Unicode應運而生。Unicode把所有語言都統一到一套編碼里,這樣就不會再有亂碼問題了。
Unicode標准也在不斷發展,但最常用的是用兩個字節表示一個字符(如果要用到非常偏僻的字符,就需要4個字節)。現代操作系統和大多數編程語言都直接支持Unicode。
現在,分析一下ASCII編碼和Unicode編碼的區別:
ASCII編碼是1個字節,而Unicode編碼通常是2個字節。
字母A用ASCII編碼是十進制的65,二進制的01000001;
字符0用ASCII編碼是十進制的48,二進制的00110000;
漢字“中”已經超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。
如果把ASCII編碼的A用Unicode編碼,只需要在前面補0就可以,因此,A的Unicode編碼是00000000 01000001。
但如果統一成Unicode編碼,亂碼問題從此消失了。但是,如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不划算。
第四種:UTF-8
基於節約的原則,出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節,常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符才會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間了。如下所示:
從上面的表格還可以發現,UTF-8編碼有一個額外的好處,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續工作。
我們總結一下現在計算機系統通用的字符編碼工作方式:
在計算機內存中,統一使用Unicode編碼,當需要保存到硬盤或者需要傳輸的時候,就轉換為UTF-8編碼。
用記事本編輯的時候,從文件讀取的UTF-8字符被轉換為Unicode字符到內存里,編輯完成后,保存的時候再把Unicode轉換為UTF-8保存到文件。如下圖:
三 編 碼
ascii:字母,數字,特殊字符。沒有中文。一個字節一個字符。 2**8 = 256,所以,ASCII碼最多只能表示 256 個符號。
萬國碼:
unicode :
A: 0000 0010 0000 0010 兩個字節,表示一個字符。
中: 0000 0010 0000 0010 兩個字節,表示一個字符。
升級:
A: 0000 0010 0000 0010 0000 0010 0000 0010 四個字節,表示一個字符。
中: 0000 0010 0000 0010 0000 0010 0000 0010 四個字節,表示一個字符。
缺點: 占空間,浪費資源。
utf-8:最少用一個字節,表示一個字符.
A: 0000 0010
歐洲:0000 00100000 0010
中文:0000 0010 0000 0010 0000 0010
gbk國標:
A: 0000 0010
中: 0000 0010 0000 0010
四 編碼轉換
UTF-8 --> decode 解碼 --> Unicode
U
nicode
--> encode 編碼 --> GBK / UTF
-8
/bytes
GBK與utf-8 不能直接轉換
例如:
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# write by congcong
s = '匆匆'
print(s)
s1 = s.decode("utf-8") # utf-8 轉成 Unicode,decode(解碼)需要注明當前編碼格式
print(s1,type(s1))
s2 = s1.encode("gbk") # unicode 轉成 gbk,encode(編碼)需要注明生成的編碼格式
print(s2,type(s2))
s3 = s1.encode("utf-8") # unicode 轉成 utf-8,encode(編碼)注明生成的編碼格式
print(s3,type(s3))
規則如下:
python3 文件默認編碼是utf-8 , 字符串編碼是 unicode
以utf-8 或者 gbk等編碼的代碼,加載到內存,會自動轉為unicode正常顯示。
python2 文件默認編碼是ascii , 字符串編碼也是 ascii , 如果文件頭聲明了是gbk,那字符串編碼就是gbk。
以utf-8 或者 gbk等編碼的代碼,加載到內存,並不會轉為unicode,編碼仍然是utf-8或者gbk等編碼。