本文詳細講解字符編碼的相關知識,包括字符編碼的發展歷程,字符編碼的使用,在python中字符編碼的應用html
首先要明確:計算機中的全部數據,不管是文字、圖片、視頻、仍是音頻文件,本質上最終都是按照相似 01010101 的二進制存儲的python
1)明文狀態:相似顯示器上能看到的消息,內容等,存儲在內存中,是處於運行狀態的信息,通常是用Unicode萬國碼存儲的數據流(或者叫信息流,字節流等)
2)文件狀態:相似硬盤文本文件中存儲的數據或者信息,相對來講是處於靜止的狀態,存儲方式爲二進制0101
3)人能夠看懂顯示器上的明文,計算機能夠看懂文本中的二進制數據
4)將明文(內存中的信息流)從內存中保存到硬盤文件中的過程須要用到「編碼」操做,將文本內容從硬盤讀到內存中的過程須要用到「解碼」操做
5)「編碼」就是咱們保存文件的過程,解碼」就是咱們打開文件的過程,這兩個過程是互逆的linux
顯示器能夠看到的漢字或英文就是字符程序員
不一樣編碼下一個字符佔用的內存或磁盤空間不一樣編程
是計算機存儲的最小單位,一字節等於八位
是計算機編程語言中的數據類型和語言字符。json
數據傳輸的最小單位vim
數據存儲是以「字節」(Byte)爲單位,數據傳輸大可能是以「位」(bit)爲單位,
一個位就表明一個0或1(即二進制),每8個位組成一個字節windows
1)數據的存儲與傳輸
數據存儲是以10進製表示,數據傳輸是以2進製表示的,因此1KB不等於1000B。網絡
1KiB(Kilobyte)=1000byte 1MiB(Megabyte)=1000000byte 1KB(Kibibyte)=1024byte 1MB(Mebibyte)=1048576byte
2)硬盤標稱容量與實際容量編程語言
硬盤生產商是以十進制,GiB(即10的3次方=1000,如1MiB=1000KB)計算的,
而電腦是以2進制,GB(即2的10次方, 如1MB=1024KB)計算的
可是國內用戶通常理解爲1MiB=1M=1024 KB, 因此爲了便於中文化的理解,翻譯MiB爲MB也是能夠的。
3)單位轉換
1B=1Byte=8bit 1KB=1024B 1MB=1024KB 1GB=1024MB 1TB=1024GB 1PB=1024TB 1EB=1024PB 1ZB=1024EB 1YB=1024ZB 1BB=1024YB
======== 分割線 =======
1)全稱:美國標準信息交換代碼,American Standard Code for Information Interchange
2)設計初衷:爲了與計算進行交互設計出ASCII碼,是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其餘西歐語言
3)設計原理:計算機上的數據都是以二進制的形式存儲的,1個字節(8比特)能夠表示256種狀態,英文只有26個字符,再加上一些特殊字符,使用128個就夠了,計算機就可使用127個不一樣字節來存儲英語文字,就是ASCII編碼
最開始的時候8位中的最高位是沒有用到的,後來爲了表示拉丁文,將最高位用上造成擴展ASCII編碼,一個字節就用滿了。
4)編碼規定:每一個字符(英文字符)最多隻能用一個字節(8 位bit)來表示,全部字符都各佔1個字節
即:2**8 = 256-1,因此,ASCII碼最多隻能表示 255 個符號。
1)設計初衷:計算機進入中國後,沒法顯示中文,現有的ASCII已經被佔滿了沒法編碼中文,因而制定GB2312,
2)設計原理:將ASCII碼擴展的第八位對應的拉丁文所有刪掉,規定一個小於127的字符與原來的意義相同,當兩個大於127的字符連接在一塊兒的時候,就表示一個漢字,前面一個字節爲高字節(0xA1-0xF7),後面一個字節爲低字節(0xA1-0xFE),這樣能夠表示7445箇中文字符
3)編碼特色:收錄7445箇中文字符,6763個漢字和682個其餘符號,GB2312是對ASCII的中文擴展,是支持中文的第一張表
1)設計初衷:因爲漢字的數量太大,GB2312不能知足需求
2)設計原理:規定只要第一個字節大於127就固定表示一個漢字,無論後面的是否是擴展字符集裏面的內容,擴展後的編碼爲GBK1.0版本
3)編碼特色:GBK包括了GB2312的全部內容,收錄21886箇中文字符(包括繁體)和符號
4)編碼規定:1箇中文字符佔2個字節
1)設計初衷:是爲了取代GBK1.0的正式國家標準,
2)設計原理:略
3)編碼特色:該標準收錄27484個漢字,和其餘藏文,蒙文,維吾爾文,繁體,日文,朝鮮語等主要的少數名族文字,GB18030相對GBK增長的字符普通人很難用到
4)編碼規定:1箇中文字符佔2個字節
1)其餘名稱:也叫統一碼,單一碼
2)設計初衷:因爲ASCII碼沒法表示世界上全部國家和地區的文字和符號,每一個國家都搞本身的編碼,彼此之間互不支持,帶來不少麻煩,因此設計出Unicode
3)編碼特色:能夠提供65535種字符,支持了全球各個國家的語言編碼,且包含了與全部國家編碼的映射關係
4)編碼規定:全部的文字和符號最少由2個字節(16位)來表示,可能更多,通常是2-4個字節
即:2**16 = 65535 = 存一個字符,統一佔用2個字節
1)設計初衷:因爲Unicode使用2-4個字節,對於英文世界的國家來講,一個字節徹底夠用,使用Unicode會形成空間浪費
2)設計原理:對Unicode進行優化產生一種可變長的字符編碼集,根據不一樣的符號變化字節長度,當字符在ASCII編碼範圍時,用一個字節表示,兼用ASCII,在存儲和傳輸時更加節省空間
3)編碼規定:英文字符用ASCII碼來存,一個英文字符佔1個字節,一個歐洲語言字符佔2個字節,1箇中文字符佔3個字節
4)其餘不一樣的Unicode擴展集:
utf-16:一個字符佔2個字節或2個以上,能夠存2的16次方,共65535個字符
utf-32:一個字符佔4個字節
5)Unicode和utf-8的關係:Unicode是內存編碼方案(規範標準),而utf-8是字符集,是保存和傳輸Unicode的是實現方式
通常不直接用Unicode,而是用UTF-8等字符編碼
注意: 1)以上幾種編碼,後面的編碼兼容前面的標準,在這些編碼中,英文和中文能夠統一處理。 unicode向下兼容gb2312 , gbk 2)區分中文編碼的方法是高字節的最高位不爲0。 3)按照程序員的習慣,GB23十二、GBK1.0到GB18030都屬於雙字節字符集 (DBCS)。 4)中國規定:進入中國的軟件必須支持GBK,PC平臺要求必須能支持GB18030,嵌入式產品,如手機,MP3等不作要求,只須要支持GB2312便可 5)不管以何種編碼在內存裏顯示字符,存在硬盤上後都是二進制編碼 6)在硬盤上以何種編碼存的數據,必須以原來的編碼讀取,不然會亂碼
BIG5 (1984):臺灣設計,13053個繁體中文
Shift-JIS,日本字符
ks_c_5601(1987),韓國字符
TIS-620,泰國編碼
1)不一樣的國家和地區制定了不一樣的標準,由此產生了 GB23十二、GBK、Big五、Shift_JIS 等各自的編碼標準。這些使用 1 至 4 個字節來表明一個字符的各類漢字延伸編碼方式,稱爲 ANSI 編碼
(American National Standards Institute美國國家標準學會)
2)在簡體中文Windows操做系統中,ANSI 編碼表明 GBK 編碼;
3)在日文Windows操做系統中,ANSI 編碼表明 Shift_JIS 編碼。
4)不一樣 ANSI 編碼之間互不兼容,當信息在國際間交流時,沒法將屬於兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。 固然對於ANSI編碼而言,0x00~0x7F之間的字符,依舊是1個字節表明1個字符。這一點是ANSI編碼與Unicode編碼之間最大也最明顯的區別。
1)字符編碼的發展:
ASCII -->GB2312 ->GBK1.0(GBK)-->GB18030
ASCII -->unicode -->utf-8/utf-16
2)不一樣字符編碼佔用的磁盤空間大小
1)ASCII碼中:一個英文字符(拉丁文)佔1個字節,8位,不能存中文,因此出了Unicode 2)GBK中:一箇中文字符佔用2個字節,1個英文字符佔用1個字節 3)unicode中:默認全部中英文字符都佔2個字節,16位, 4)utf-8中:一箇中文字符佔用3個字節,一個英文字符默認佔1個字節,8位
Python解釋器在加載 .py文件中的代碼時,須要使用指定的字符編碼將內容進行轉換爲0101這種二進制代碼,交付給CPU處理
Python2.x解釋器默認編碼是ASCII碼,不支持中文,要使用中文,需提早申明字符編碼
Python3.x解釋器默認編碼是unicode,支持中文,不須要申明字符編碼
1)編輯py程序msg.py,在第一行申明須要使用的字符編碼
vim msg.py ------------------------- # -*- coding:utf-8 -*- # 放在第一行; # encoding:utf-8 # 放在第一行; # coding:utf-8 # 放在第一行; msg = "今每天氣真不錯" print(msg) ------------------------- python msg.py --->今每天氣真不錯
也能夠用這種:
#!/usr/bin/env python # -*- coding: utf-8 -*-
2)變量值前加個字母「u」,表明用Unicode顯示
vim msg.py ------------------------- msg = u"今每天氣真不錯" print(msg) ------------------------- python msg.py --->今每天氣真不錯
1)中文Windows默認編碼:GBK(GBK1.0)
切換字符編碼爲GBK的windows命令:
chcp 936
2)Mac和Linux默認編碼:UTF-8
3)打印系統默認編碼
import sys print(sys.getdefaultencoding())
1)在Python2中,字符串能夠存成兩種類型:str和unicode,他們在內存中的存儲方式不一樣,但均可以直接打印到屏幕上
str存儲byte字節數據,用<type 'str'>表示,存入的是二進制bytes的str類型,打印到屏幕時會自動轉爲Unicode,因此能夠打印中文,也能夠手動轉換爲Unicode打印到屏幕 unicode存儲unicode數據,用<type 'unicode'>表示,直接保存成Unicode數據,能夠直接打印內存中的Unicode數據到屏幕,也能夠編碼爲str字符串打印出來
str1:UTF-8 --> str1.decode("utf-8") -->str1-2:Unicode --> str1-2.encode("gbk")-->str1-2:GBK str2:GBK --> str2.decode("gbk") -->str2-2:Unicode --> str2-2.encode("utf-8") -->str2-2:UTF-8
2)兩種類型能夠經過編碼解碼進行相互轉換,也能夠進行字符串拼接(bytes數據會自動轉碼爲Unicode)
3)只要數據所有是ASCII,自動轉換就正常,不然會出現亂碼,出現UnicodeDecodeError 的錯誤
Python2編碼讓程序在處理 ASCII 的時候更加簡單,代價就是在處理非 ASCII 的時候將會失敗
實例演示1:
[root@zssrv ~]# python2 ---------------------------- str1='中國hello123' print type(str1) # <type 'str'>,存入的是str類型 print repr(str1) # '\xe4\xb8\xad\xe5\x9b\xbdhello123',內存中存儲的二進制bytes數據 print str1 # 中國hello123,打印到屏幕時會自動轉爲Unicode,因此能夠打印中文 a = str1.decode('utf8') # str類型也就是二進制bytes,手動解碼成Unicode讀出來 print type(a) # <type 'unicode'>,轉換爲了Unicode print repr(a) # u'\u4e2d\u56fdhello123',內存中存儲的Unicode數據 print a # 中國hello123,手動轉換成的a是Unicode因此能夠打印中文 a2 = str1.decode('gbk') # 但若是用錯誤的編碼解析,就會報錯 # --->UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence str2=u'你好hello123' print type(str2) # <type 'unicode'>,直接保存成了Unicode數據 print str2 # 你好hello123,直接打印內存中的Unicode數據 print repr(str2) # u'\u4f60\u597dhello123',內存中存儲的Unicode數據 b = str2.encode('utf-8') # Unicode類型的,能夠編碼爲str讀出來 print b # 你好hello123 print type(b) # <type 'str'> print repr(b) # '\xe4\xbd\xa0\xe5\xa5\xbdhello123' ---------------------------
實例演示2:字符串拼接
print (u"hello"+"world") # hello中國 print ("hello"+u"中國") # hello中國 print (u"hello"+"中國") --->UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
1)在Python3中,字符串有兩種數據類型:str(unicode)和bytes,但內存中都表示爲Unicode,能夠直接打印到屏幕
str類型存unicode數據,用<class 'str'>表示,使用」\uxxxx「顯示,也就是內存中的文本數據流 bytse類型存bytes字節數據,用<class 'bytes'>表示,使用b’\uxxxx’這種二進制格式顯示,也就是硬盤文本文件中的內容
2)在Python命令行中,Unicode字符會默認的轉換成可顯示的字符串格式,而不會顯示其自己的二進制碼。
3)Python 3最重要的新特性之一是對文本和二進制數據做了更爲清晰的區分,再也不會對bytes字節串進行自動解碼。
4)不能拼接字符串和字節包,不能在字節包裏搜索字符串(反之亦然),不能將字符串傳入參數爲字節包的函數(反之亦然)。
實例演示:Python3中
import json str3 = '你好' print(str3) # 你好,能夠直接打印字符串 print(type(str3)) # <class 'str'>,在內存中保存成Unicode數據 print(json.dumps(str3)) # "\u4f60\u597d" c = str3.encode('utf8') # 能夠手動編碼爲bytes類型,二進制數據 print(c) # b'\xe4\xbd\xa0\xe5\xa5\xbd',直接打印二進制數據,而不是字符內容 print(type(c)) # <class 'bytes'> u = c.decode('utf8') # 再次用utf-8解碼爲str字符串類型(Unicode數據) print(u) # 你好 print(type(u)) # <class 'str'>,查看是Unicode數據 print(json.dumps(u)) # "\u4f60\u597d" str4 = u'你好' print(str4) # 你好,能夠直接打印,不必前面加u print(type(str4)) # <class 'str'> print(json.dumps(str4)) # "\u4f60\u597d"
實例演示:字符串拼接,不一樣類型,確定會報錯
print(b'hello'+'world') # TypeError: can't concat str to bytes
1)在Python 2中,print是一個語句(statement);在Python 3中變成了函數(function)。
2)不管py2,仍是py3,與明文直接對應的就是unicode數據,打印unicode數據就會顯示相應的明文(包括英文和中文)
3)在內存中的unicode,存到硬盤上或網絡傳輸須要轉成gbk/utf-8(自動轉)
4)音視頻文件是用二進制bytes字節數據保存的
5)Python3裏只有Unicode纔會打印中文,s.encode("gbk")不會打印中文(不去編碼表裏找),而是顯示bytes數據
經過這種方式就是想告訴別人:py3裏想要看到字符,必須是Unicode,其餘的編碼一概按bytes格式展現
1)Python解釋器的默認編碼(py2,py3)
2)Python源文件文件編碼(申明的編碼utf-8,gbk)
3)Terminal使用的編碼(cmd等)與py文件的不匹配
4)操做系統的語言設置(windows,linux,mac等)
EmEditor GB2312
pycharm unicode
notepad++ utf-8
python 之路,致那些年,咱們依然沒搞明白的編碼
http://www.cnblogs.com/alex3714/articles/7550940.html
py編碼終極版
http://www.cnblogs.com/yuanchenqi/articles/5956943.html
字符串相關
http://www.diveintopython3.net/strings.html
unicode與gbk的映射表
http://www.unicode.org/charts/
完畢,呵呵呵呵