成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用 Python 理清編碼問題:Unicode萬國碼

開發(fā) 后端
為解決語言各自為政的編碼,人們提出了Unicode編碼方案,這個方案簡單粗暴:把世界上所有語言字符統(tǒng)一編碼。Unicode的兩種方案UCS-2和UCS-4,可使用空間分別達(dá)到2^16和2^32個:外星人到訪地球之前,應(yīng)該是夠用的。

[[392291]]

Python中文社區(qū) ID:python-china

Unicode——萬國碼

為解決語言各自為政的編碼,人們提出了Unicode編碼方案,這個方案簡單粗暴:把世界上所有語言字符統(tǒng)一編碼。Unicode的兩種方案UCS-2和UCS-4,可使用空間分別達(dá)到2^16和2^32個:外星人到訪地球之前,應(yīng)該是夠用的。

我們看幾個字符的Unicode編碼碼位(code point)是怎樣的: 

  1. ls = 'abAB鞏★☆' 
  2. print([ord(l) for l in ls]) 

結(jié)果:[97, 98, 65, 66, 24041, 9733, 9734]。可見,字母abAB的Unicode碼位和其ASCII碼位一致,所以字符為字母時兩者兼容,而漢字鞏的碼位為24041(0x5de9),與之前的GB系列編碼47534(0xb9ae)不同,所以Unicode和GB系列編碼之間是不完全兼容的:只有ASCII部分兼容。

所有國家的人都使用Unicode編碼之后,擴(kuò)展、亂碼問題都不復(fù)存在:所有人類語言字符都有了一個統(tǒng)一的編碼碼位,溝通中我們寫出的每個數(shù)字編碼,都有唯一的字符與他對應(yīng)。Python中chr函數(shù)返回Unicode碼位對應(yīng)的字符。 

  1. >>> print([chr(i) for i in [123,957,24041]]) 
  2. ['{''ν''鞏'

那么我們可以使用強(qiáng)大的Unicode進(jìn)行編碼了么?

  1. >>> ls = 'abAB鞏★☆' 
  2. >>> ls.encode('Unicode'
  3. Traceback (most recent call last): 
  4.   File "<stdin>", line 1, in <module> LookupError: unknown encoding: Unicode 

未知編碼Unicode!這是因為,并不存在Unicode碼這種編碼形式,Unicode只是一個碼位表,它只是建立了字符和整數(shù)之間的映射。至于整數(shù)碼位(code point)如何存儲成字節(jié),先存高位低位,有沒有特殊標(biāo)志,Unicode并不直接決定,而是交給具體編碼來考慮這些細(xì)節(jié):UTF-32,UTF-16和UTF-8。

UTF-32 四字節(jié)為單位

UTF-32,顧名思義,是用32位,也就是四個字節(jié)來存儲一個字符的編碼方案。 

  1. >>> 'aA鞏'.encode('utf-32LE'
  2. b'a\x00\x00\x00A\x00\x00\x00\xe9\x5d\x00\x00' 

可見,所有的字符,都使用了四個字節(jié)來存儲:每個字節(jié)除了Unicode碼位之外,不足用\x00來填充。此法簡單明了,Unicode碼位不用轉(zhuǎn)換,直接填充。但大量的\x00造成了極大的浪費(fèi)。有沒有辦法解決這種浪費(fèi)了?壓縮下用兩位行不行?

UTF-16 兩字節(jié)為單位

當(dāng)用UTF-16來編碼時。 

  1. >>> 'aA鞏'.encode('utf-16LE'
  2. b'a\x00A\x00\xe9\x5d' 

兩個字節(jié)對絕大多數(shù)Unicode碼位來說是夠用的,不夠用的話系統(tǒng)自動用四位表示。這是系統(tǒng)實現(xiàn),我們無需關(guān)心。UTF-16編碼后的字節(jié)序列和字符,依然能夠一一對應(yīng)起來。UTF-16其實有兩種編碼方法,分別為上例的UTF-16LE和如下的UTF-16BE,測試: 

  1. >>> 'aA鞏'.encode('utf-16BE'
  2. b'\x00a\x00A\x5d\xe9' 

兩者基本一樣,只是高低字節(jié)位置發(fā)生了顛倒。LE和BE后綴,表示小字節(jié)序(little endian)和大字節(jié)序(big endian)。這是計算機(jī)內(nèi)部關(guān)于字節(jié)的MSB(大權(quán)重字節(jié))放在字節(jié)的開頭還是結(jié)尾的具體實現(xiàn)細(xì)節(jié)。

《格列佛游記》中,小人國國民為吃雞蛋先吃大頭或小頭,針鋒相對,組成了兩個軍事對立集團(tuán)big endians和little endians,相互間多次發(fā)動戰(zhàn)爭。

那么兩個字節(jié)就是Unicode編碼的極限了么?

UTF-8 變長字節(jié)編碼

能不能用可變數(shù)目的字節(jié)來存儲文本呢?如果存儲的是英文文本的話,每個字符只用一個字節(jié)就可以;漢字的話,再進(jìn)行擴(kuò)展。如此來進(jìn)一步節(jié)省存儲空間。答案是可以的,這就是可變長度編碼UTF-8。 

  1. >>> 'aA鞏'.encode('utf-8'
  2. b'aA\xe5\xb7\xa9' 

這是目前最短的字節(jié)序列,因為aA分別存儲成了一個字節(jié)。需要注意的是,UTF-32和UTF-16中,鞏的字節(jié)序列是0x5de9,但在UTF-8中,字節(jié)序列變成了0xe5b7a9。這說明UTF-8編碼不是簡單地把Unicode碼位直接存儲進(jìn)字節(jié)序列中,而是進(jìn)行了某些轉(zhuǎn)換。這些轉(zhuǎn)換,保證了英文用一位存儲,漢語等較大字符多字節(jié)存儲。那么是如何轉(zhuǎn)換的呢?

UTF-8 編碼轉(zhuǎn)換規(guī)則

本部分過于細(xì)節(jié),可略過。UTF-8實現(xiàn)了可變長度的編碼,為解碼時區(qū)分可變長度究竟多長,需要在字節(jié)序列里使用特殊模板。UTF-8編碼遵循以下規(guī)則:

  • 0x00-0x7F之間的碼位,兼容ASCII碼,單字節(jié)直接存儲在以下模板 0*** ****
  • 0x80-0x7ff之間,使用兩個字節(jié)存儲,字節(jié)模板是110* **** 10** ****
  • 0x800-0xffff之間,使用三個字節(jié)存儲,字節(jié)模板是1110 **** 10** **** 10** ****
  • 0x10000-0x1fffff之間,使用四個字節(jié)存儲,字節(jié)模板是1111 0*** 10** **** 10** **** 10** ****

以漢字鞏為例,其Unicode碼位為0x6c49,二進(jìn)制位110 1100 0100 1001。位于第三行范圍,所以需要三個字節(jié)來存儲,寫出模板,1110 **** 10** **** 10** ****,使用二進(jìn)制,從右向左填充,不足部分補(bǔ)零,可得結(jié)果1110 0110 1011 0001 1000 1001,十六進(jìn)制為0xe6 0xb7 0x89,所以鞏編碼為UTF-8的字節(jié)序列形式為0Xe6b789。讓我們從UTF-8編碼轉(zhuǎn)換細(xì)節(jié)中,回到UTF三種編碼的長度問題上來。

UTF三種編碼后的長度

以上三種編碼方式,由于壓縮率不用,導(dǎo)致文件長度也不同,以下程序比較當(dāng)文本為漢字和英語內(nèi)容時,三種不同編碼的長度: 

  1. es = 'abcdefghij' 
  2. cs = '莫愁前路無知己,天下誰人不識君。' 
  3.  
  4. codes = ['utf-32le','utf-16le','utf-8'
  5.  
  6. print([len(es.encode(code)) for code in codes]) 
  7. print([len(cs.encode(code)) for code in codes]) 

輸出為 [40, 20, 10] [64, 32, 48] 可見,對于英文來說,UTF-8比UTF-16和UTF-32編碼都要有優(yōu)勢;對漢字來說,最有優(yōu)勢的反而是UTF16編碼。這是因為UTF-16編碼中,大部分漢字采用2Byte存儲,而UTF-8中漢字需要三個字節(jié)存儲。在日常生活中,因為考慮到最大兼容性,UTF-8使用的最為廣泛。至此,我們從ASCII碼到GB系列編碼,再到Unicode和相應(yīng)的UTF系列編碼,一路進(jìn)化,擁有了一個包羅萬碼,不會亂碼和有較高壓縮率的字符編碼系統(tǒng)。可以使用了么?沒有!因為我們只是編碼了文本自身,并沒有記載具體用了那個編碼:當(dāng)我們發(fā)送一份文件后,除非告訴對方,否則對方不知道應(yīng)該該用什么編碼打開它。解決這個問題,我們留待下篇文章分析。

總結(jié)

  • Unicode統(tǒng)一了世界各語言字符。Unicode幾種編碼形式中;
  • UTF-32簡單,但浪費(fèi)嚴(yán)重。
  • UTF-16使用兩個字節(jié)為單位存儲,節(jié)省了空間。
  • UTF-8使用一個字節(jié)直接存儲,是效率、空間的平衡。 

 

 

責(zé)任編輯:龐桂玉 來源: Python中文社區(qū)
相關(guān)推薦

2012-07-03 16:46:39

實時監(jiān)控萬國數(shù)據(jù)

2012-08-17 17:18:24

數(shù)據(jù)中心萬國數(shù)據(jù)

2011-12-12 17:16:10

萬國數(shù)據(jù)數(shù)據(jù)中心

2016-11-02 22:15:57

萬國數(shù)據(jù)

2019-01-26 12:28:56

萬國數(shù)據(jù)

2011-07-20 14:38:11

萬國數(shù)據(jù)企業(yè)品牌

2013-11-20 13:49:08

數(shù)據(jù)中心電子城數(shù)據(jù)中心萬國數(shù)據(jù)

2014-04-23 21:11:09

與惠普同行

2017-01-07 11:00:05

阿里萬國數(shù)據(jù)數(shù)據(jù)中心

2012-07-10 14:08:58

IT高可用管理體系萬國數(shù)據(jù)

2014-09-26 22:16:46

伊頓

2013-06-08 16:00:28

萬國數(shù)據(jù)大數(shù)據(jù)云計算

2014-06-27 16:24:21

萬國數(shù)據(jù)云計算互聯(lián)網(wǎng)金融

2016-11-28 16:12:32

萬國數(shù)據(jù)

2014-06-23 17:54:56

萬國數(shù)據(jù)

2020-10-21 15:41:46

萬國數(shù)據(jù)

2019-01-23 11:25:56

混合云架構(gòu)安全

2020-07-16 10:15:48

萬國數(shù)據(jù)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲精品视频免费看 | 久草中文网 | 欧美高清一级片 | 欧美精品一区二区三区在线 | 久久专区 | 成人av免费| 久久青 | 亚洲高清在线 | 亚洲综合字幕 | 国产视频1 | 国产精品日韩一区二区 | 毛片韩国 | 亚洲自拍偷拍视频 | 亚洲欧美中文日韩在线 | 精品国产一区二区三区免费 | 理论片免费在线观看 | 天天插天天舔 | 午夜欧美一区二区三区在线播放 | 国产一区二区在线视频 | 91视频一88av | 亚洲欧洲日韩精品 中文字幕 | 欧美视频三区 | 男女视频免费 | 国产一区二区三区在线观看免费 | 国产精品国产三级国产aⅴ浪潮 | 欧美一区二 | 狠狠的日 | 久久久久久久av | 中文字幕亚洲欧美日韩在线不卡 | 日韩在线欧美 | 欧美一区日韩一区 | 男人的天堂在线视频 | 综合久久久| 中文字幕一区二区三区四区五区 | 91资源在线| 毛片a级 | 国产98色在线 | 日韩 | 91精品国产综合久久久久久丝袜 | 国产乱码精品1区2区3区 | 毛片免费在线观看 | 天色综合网|