字符編碼是計算機的基石,想要熟練使用計算機,就必須懂得一點字符編碼的知識,首先我們來說說字符編碼,這其實與是哪種語言並無太大聯繫,首先我們來了解幾個基本概念
字符集
字符集(Character Set)就是某個範圍內字符的集合,不同的字符集規定了字符的個數,比如 ASCII 字符集總共有128個字符,包含了英文字母、阿拉伯數字、標點符號和控制符。而 GB2312 字符集定義了7445個字符,包含了絕大部分漢字字符。
字符碼
字符碼(Code Point)指的是字符集中每個字符的數字編號,例如 ASCII 字符集用 0-127 連續的128個數字分別表示128個字符,例如 "A" 的字符碼編號就是65。
字符編碼
字符編碼(Character Encoding)是將字符集中的字符碼映射為字節流的一種具體實現方案,常見的字符編碼有 ASCII 編碼、UTF-8 編碼、GBK 編碼等。某種意義上來說,字符集與字符編碼有種對應關係,例如 ASCII 字符集對應 有 ASCII 編碼。ASCII 字符編碼規定使用單字節中低位的7個比特去編碼所有的字符。例如"A" 的編號是65,用單字節表示就是0×41,因此寫入存儲設備的時候就是b'01000001'。
編碼(encode)、解碼(decode)
編碼的過程是將字符串轉換成字節流,解碼的過程是將字節流解析為字符串。
理解了這些基本的術語概念後,我們就可以開始討論計算機的字符編碼的演進過程了。
字符編碼演進
一、ASCII碼
英語用128個編碼就夠了,但是用來表示歐洲其他語言,顯然就不夠了,即使是歐洲國家擴充到256個,但是每個國家可能每個字母對應的含義都不一樣,至於到亞洲國家的文字,那顯然就更不夠用了,光中文就是上萬字
正如這樣世界上存在著各種編碼方式,並且同一個二進位數字可以被解釋成為不同的符號,因此要打開一個文件,必須提前知道它的字符編碼,否則就會產生亂碼,正是這種背景,unicode應運而生,正如它名字一般,這是一種所有符號的編碼,這樣也就不會有亂碼問題了
需要注意的是,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編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不划算。
三、UTF-8
基於以上出現了UTF-8 ,這裡要重要提出來的是,UTF-8是unicode的實現方式之一,UTF-8的最大的特點是:它是一種變長的編碼方式,使用1~4個字節表示一個符號,根據不同的符號而變化編碼長度,UTF-8 的編碼規則很簡單,只有二條:
1)對於單字節的符號,字節的第一位設為0,後面7位為這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。
2)對於n字節的符號(n > 1),第一個字節的前n位都設為1,第n + 1位設為0,後面字節的前兩位一律設為10。剩下的沒有提及的二進位位,全部為這個符號的 Unicode 碼。
下表總結了編碼規則
Unicode符號範圍 | UTF-8編碼方式(十六進位) | (二進位)--+0000 0000-0000 007F | 0xxxxxxx0000 0080-0000 07FF | 110xxxxx 10xxxxxx0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx搞清楚了ASCII、Unicode和UTF-8的關係,我們就可以總結一下現在計算機系統通用的字符編碼工作方式:
在計算機內存中,統一使用Unicode編碼,當需要保存到硬碟或者需要傳輸的時候,就轉換為UTF-8編碼。
用記事本編輯的時候,從文件讀取的UTF-8字符被轉換為Unicode字符到內存裡,編輯完成後,保存的時候再把Unicode轉換為UTF-8保存到文件:
瀏覽網頁的時候,伺服器會把動態生成的Unicode內容轉換為UTF-8再傳輸到瀏覽器:
所以你看到很多網頁的源碼上會有類似<meta charset="UTF-8" />的信息,表示該網頁正是用的UTF-8編碼。
搞清楚了字符編碼的一些基本類型後,我們來說說python的字符串
在 python2 中和字符串相關的數據類型有 str 和 unicode 兩種類型,它們繼承自 basestring,而 str 類型的字符串的編碼格式可以是 ascii、utf-8、gbk等任何一種類型。
在字符編碼轉換操作時,遇到的最多的就是UnicodeEncodeError 和UnicodeDecodeError 錯誤,這些錯誤的根本原因在於python2默認使用ascii編碼進行decode和encode操作,由於目前python版本基本都是以python3為主,所以亂碼等由於編碼不一致的問題都好解決了了在最新的Python 3版本中,字符串是以Unicode編碼的,也就是說,Python的字符串支持多語言,例如:
>>> import sys>>> print(sys.getdefaultencoding())utf-8>>> print('包括中文也很好支持')包括中文也很好支持對於單個字符的編碼,Python提供了ord()函數獲取字符的整數表示,chr()函數把編碼轉換為對應的字符:
>>> ord('Z')90>>> ord('熊')29066>>> chr(29066)'熊'python3中,str是unicode,當程序執行時,無需加u,str也會被以unicode形式保存新的內存空間中,str可以直接encode成任意編碼格式,s.encode('utf-8'),s.encode('gbk')
#unicode(str)encode---->utf-8(bytes)
#utf-8(bytes)decode---->unicode好了今天就到這了,算是對python字符編碼的一個總結吧,如果覺得對你有幫助,別忘了告訴我哦,也算是對我的一種鼓勵