Python 2.x 字符編碼問題

ASCII,Unicode,UTF-8 和 UTF-16

ASCII是一種我們最爲熟悉的編碼方式,從大一入學學C語言的時候就學過。那麼到底什麼是編碼呢?我們知道數據實際上是以二進制的形式存儲的,而我們人類可讀的卻是特定形式的字符(如’a’,’b’,’c’),而編碼就是這樣一種映射關係,它把每一個字符映射爲一個二進制數,使得我們可以將數據存到內存或磁盤裏。而 ASCII 碼將英文字符映射爲 8 比特二進制數,最多可以編碼2**8-1=255 種不同字符。(ASCII 碼
但是世界上有很多種語言,比如漢語這種擁有上萬字符的語言,用 ASCII 來編碼顯然是不夠的,所以許多國家就出臺了自己的編碼規約,我國的簡體中文的編碼方式是 GBK。但是每個國家所出臺的字符的編碼方式,並不能兼容,帶來了不小的麻煩。
那麼 Unicode 又是什麼呢?實際上 Unicode 是一種編碼方式,只是它將字符映射爲 16 比特長的二進制碼,希望藉此將所有語言的編碼統一起來。所以 Unicode 是一種將一個字符轉換爲 16 個比特的編碼方式,最多可以表示 65535 個不同字符(實際上現在 Unicode 可以表示超過百萬個字符,但這不是今天的重點)。
那麼 UTF-8,UTF-16 和 Unicode 又是什麼關係?以 UTF-8 爲例,
UTF-8 全稱是 UCS Transfer Format 8,UCS 傳輸格式,UTF-8表示每次傳輸 8 個比特。實際上 Unicode 只規定了序號和字符之間的映射關係,沒有規定實際的編碼方式。而 UTF-8 就是 Unicode 的一種編碼實現,它是一種變長的編碼,爲保證對 ASCII 碼的兼容,其編碼方式如下,表中 x 的地方就是對應 Unicode 各二進制位的位置:

Unicode 十六進制對應 UTF-8 編碼二進制表示
0000 0000-0000 007F0xxxxxxx
0000 0080-0000 07FF110xxxxx 10xxxxxx
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

例如 “我”這個漢字的 Unicode 爲”+U6211”,對應二進制是
0110 001000 010001,因爲常用漢字的 UTF-8 碼都是三個字節長,所以它對應的的 UTF-8 碼就是 1110(0110) 10(001000) 10(010001),對應的三個十六進制數就是 0xe6,0x88,0x91。

一些 Python 裏的例子

>>> s = '我愛中國'
>>> s # 這是 s 的字節碼
'\xe6\x88\x91\xe7\x88\xb1\xe4\xb8\xad\xe5\x9b\xbd'
>>> len(s)
12
>>> s1 = s.decode('utf-8') # 使用 UTF-8 進行解碼
>>> s1 # 這是 s 的 Unicode 編碼
u'\u6211\u7231\u4e2d\u56fd'
>>> len(s1)
4
>>> s2 = u'我愛中國'
>>> s2
u'\u6211\u7231\u4e2d\u56fd'
>>> assert s1 == s2

一些相關內容

str 和 unicode

這裏寫圖片描述

在 Python 中,Unicode 是沒有格式的,或者說 Unicode 本身就是沒有格式的,只是一個符號集,它只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲;它被用做字符串編碼基準,即要麼將 Unicode 編碼成某一個字符串,要麼某個字符串被解碼爲 Unicode。
而 str 在 Python 中是原始字節碼,需要按照對應的編碼方式進行解碼才能還原原始信息。

decode 和 encode

s.decode(encoding): 把字符串按照給定的編碼格式解碼爲 Unicode,返回值類型爲 unicode

>>> s = '中國'
>>> s
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> s.decode('utf-8')
u'\u4e2d\u56fd'

s.encode(encoding): 把 Unicode 按照給定的編碼格式進行編碼,
返回值類型爲 str

>>> s = u'中國'
>>> s
u'\u4e2d\u56fd'
>>> s.encode('gbk')
'\xd6\xd0\xb9\xfa'

參考鏈接

python字符串編碼及亂碼解決方案
Python字符編碼詳解
字符編碼筆記:ASCII,Unicode和UTF-8

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章