Python基礎-編碼與解碼

来源:http://www.cnblogs.com/OldJack/archive/2017/04/02/6658779.html
-Advertisement-
Play Games

一、什麼是編碼 編碼是指信息從一種形式或格式轉換為另一種形式或格式的過程。 在電腦中,編碼,簡而言之,就是將人能夠讀懂的信息(通常稱為明文)轉換為電腦能夠讀懂的信息。眾所周知,電腦能夠讀懂的是高低電平,也就是二進位位(0,1組合)。 而解碼,就是指將電腦的能夠讀懂的信息轉換為人能夠讀懂的信息 ...


 

一、什麼是編碼

編碼是指信息從一種形式或格式轉換為另一種形式或格式的過程。

在電腦中,編碼,簡而言之,就是將人能夠讀懂的信息(通常稱為明文)轉換為電腦能夠讀懂的信息。眾所周知,電腦能夠讀懂的是高低電平,也就是二進位位(0,1組合)。

而解碼,就是指將電腦的能夠讀懂的信息轉換為人能夠讀懂的信息。

二、 編碼的發展淵源

之前的博客中已經提過,由於電腦最早在美國發明和使用,所以一開始人們使用的是ASCII編碼。ASCII編碼占用1個位元組,8個二進位位,最多能夠表示2**8=256個字元。

隨著電腦的發展,ASCII碼已經不能滿足世界人民的需求。因為世界各國語言繁多,字元遠遠超過256個。所以各個國家都在ASCII基礎上搞自己國家的編碼。

例如中國,為了處理漢字,設計了GB2312編碼,一共收錄了7445個字元,包括6763個漢字和682個其它符號。1995年的漢字擴展規範GBK1.0收錄了21886個符號。2000年的 GB18030是取代GBK1.0的正式國家標準。該標準收錄了27484個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族文字。

  

但是,在編碼上,各國”各自為政“,很難互相交流。於是出現了Unicode編碼。Unicode是國際組織制定的可以容納世界上所有文字和符號的字元編碼方案。

Unicode規定字元最少使用2個位元組表示,所以最少能夠表示2**16=65536個字元。這樣看來,問題似乎解決了,各國人民都能夠將自己的文字和符號加入Unicode,從此就可以輕鬆交流了。

然而,在當時,電腦的記憶體容量可是寸土寸金的情況下,美國等北美洲國家是部接受這個編碼的。因為這憑空增加了他們文件的體積,進而影響了記憶體使用率,影響工作效率。這就尷尬了。

顯然國際標準在美國這邊不受待見,所以應運而生產生了utf-8編碼。

UTF-8,是對Unicode編碼的壓縮和優化,它不再要求最少使用2個位元組,而是將所有的字元和符號進行分類:ASCII碼中的內容用1個位元組保存、歐洲的字元用2個位元組保存,東亞的字元用3個位元組保存。

這樣,大家各取所需,皆大歡喜。

三、utf-8是如何節省存儲空間和流量的

當電腦在工作時,記憶體中的數據一直時以Unicode的編碼方式表示的,當數據要保存到磁碟或者網路傳輸時,才會使用utf-8編碼進行操作。

  在電腦中,”I'm 傑克"的unicode字元集是這樣的編碼表:

I	0x49        
'	0x27
m	0x6d
 	0x20
傑	0x6770
克	0x514b

  每個字元對應一個十六進位數(方便人們閱讀,0x代表十六進位數),但是電腦只能讀懂二進位數,所以,實際在電腦內表示如下:

I	0b1001001
'	0b100111
m	0b1101101
 	0b100000
傑	0b110011101110000
克	0b101000101001011

  由於Unicode規定,每個字元最少占用2個位元組,所以,以上字元串在記憶體中的實際占位如下:

I	00000000 01001001
'	00000000 00100111
m	00000000 01101101
 	00000000 00100000
傑	01100111 01110000
克	01010001 01001011

  這串字元總共占用了12個位元組,但是對比中英文的二進位碼,可以發現,英文的前9位都是0,非常的浪費空間和流量。

看看utf-8是怎麼解決的:

I	01001001
'	00100111
m	01101101
 	00100000
傑	11100110 10011101 10110000
克	11100101 10000101 10001011

  utf-8用了10個位元組,對比Unicode,少了2個位元組。但是,我們的程式中很少用到中文,如果我們程式中90%的內容都是英文,那麼可以節省45%的存儲空間或者流量。

所以,在存儲和傳輸時,大部分時候遵循utf-8編碼

  

四、Python2.x與Python3.x中的編解碼

1. 在Python2.x中,有兩種字元串類型:str和unicode類型。str存bytes數據,unicode類型存unicode數據

 

由上圖可以看出,str類型存儲的是十六進位位元組數據;unicode類型存儲的是unicode數據。utf-8編碼的中文占3個位元組,unicode編碼的中文占2個位元組。

位元組數據常用來存儲和傳輸,unicode數據用來顯示明文,那如何轉換兩種數據類型呢:

無論是utf-8還是gbk都只是一種編碼規則,一種把unicode數據編碼成位元組數據的規則,所以utf-8編碼的位元組一定要用utf-8的規則解碼,否則就會出現亂碼或者報錯的情況。

python2.x編碼的特色:

為什麼英文拼接成功了,而中文拼接就報錯了?

這是因為在python2.x中,python解釋器悄悄掩蓋掉了 byte 到 unicode 的轉換,只要數據全部是 ASCII 的話,所有的轉換都是正確的,一旦一個非 ASCII 字元偷偷進入你的程式,那麼預設的解碼將會失效,從而造成 UnicodeDecodeError 的錯誤。python2.x編碼讓程式在處理 ASCII 的時候更加簡單。你付出的代價就是在處理非 ASCII 的時候將會失敗。

2. 在Python3.x中,也只有兩種字元串類型:str和bytes類型。

str類型存unicode數據,bytse類型存bytes數據,與python2.x比只是換了一下名字而已。

還記得之前博文中提到的這句話嗎?ALL IS UNICODE NOW

python3 renamed the unicode type to str ,the old str type has been replaced by bytes.

 

Python 3最重要的新特性大概要算是對文本和二進位數據作了更為清晰的區分,不再會對bytes位元組串進行自動解碼。文本總是Unicode,由str類型表示,二進位數據則由bytes類型表示。Python 3不會以任意隱式的方式混用str和bytes,正是這使得兩者的區分特別清晰。你不能拼接字元串和位元組包,也無法在位元組包里搜索字元串(反之亦然),也不能將字元串傳入參數為位元組包的函數(反之亦然)。

註意:無論python2,還是python3,與明文直接對應的就是unicode數據,列印unicode數據就會顯示相應的明文(包括英文和中文)

 五、文件從磁碟到記憶體的編碼

當我們在編輯文本的時候,字元在記憶體對應的是unicode編碼的,這是因為unicode覆蓋範圍最廣,幾乎所有字元都可以顯示。但是,當我們將文本等保存在磁碟時,數據是怎麼變化的?

答案是通過某種編碼方式編碼的bytes位元組串。比如utf-8,一種可變長編碼,很好的節省了空間;當然還有歷史產物的gbk編碼等等。於是,在我們的文本編輯器軟體都有預設的保存文件的編碼方式,比如utf-8,比如gbk。當我們點擊保存的時候,這些編輯軟體已經"默默地"幫我們做了編碼工作。

那當我們再打開這個文件時,軟體又默默地給我們做瞭解碼的工作,將數據再解碼成unicode,然後就可以呈現明文給用戶了!所以,unicode是離用戶更近的數據,bytes是離電腦更近的數據。

其實,python解釋器也類似於一個文本編輯器,它也有自己預設的編碼方式。python2.x預設ASCII碼,python3.x預設的utf-8,可以通過如下方式查詢:

import sys
print(sys.getdefaultencoding())

如果我們不想使用預設的解釋器編碼,就得需要用戶在文件開頭聲明瞭。還記得我們經常在python2.x中的聲明嗎?

#coding:utf-8

如果python2解釋器去執行一個utf-8編碼的文件,就會以預設的ASCII去解碼utf-8,一旦程式中有中文,自然就解碼錯誤了,所以我們在文件開頭位置聲明 #coding:utf-8,其實就是告訴解釋器,你不要以預設的編碼方式去解碼這個文件,而是以utf-8來解碼。而python3的解釋器因為預設utf-8編碼,所以就方便很多了。

 

 

參考資料

1. http://www.cnblogs.com/yuanchenqi/articles/5956943.html

2. http://www.cnblogs.com/284628487a/p/5584714.html

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線性表之順序表 一、頭文件:SeqList.h //順序線性表的頭文件#include<iostream> const int MaxSize = 100;//定義順序表SeqList的模板類template<class DataType>class SeqList{public: //順序表無參構 ...
  • JSR330 DI JSR 330 ,提供了一種可重用的、可維護、可測試的方式來獲取Java對象。也稱為Dependency Injection 。 DI應該都不陌生,因為它就是Spring core之一。在Spring盛行後,Google也提供了一種DI實現:Guice。因為這兩個DI容器的盛行, ...
  • 一、單例模式(Singleton) 1、單例模式應用場景: ①Servlet ②任務管理器 ③鏈接池 ④Spring中每個 bean 預設是單例 ⑤網站計數器 2、單例要求 ①構造器私有 ②私有的靜態變數 ③公共的靜態的可以訪問私有的靜態變數的方法 結論:由結果可以得知單例模式為一個面向對象的應用程 ...
  • 我在mvc配置文件中加上下麵這個配置就好了 <mvc:annotation-driven></mvc:annotation-driven>,需要在開頭引用如下命名空間xmlns:mvc="http://www.springframework.org/schema/mvc 它自動配置DefaultAn ...
  • 聲明 轉載請註明出處! Reprint please indicate the source! http://www.hiknowledge.top/?p=86&preview=true 什麼是JMS JMS即Java消息服務(Java Message Service)應用程式介面,是一個Java平 ...
  • 在牛客網上做到的一道題,挺簡單基礎的,不過也寫一下,哈哈! 統計一個數字在排序數組中出現的次數: 可定義一個用於統計數字個數的變數count,然後從前往後遍曆數組,看是否與所求數字相等,如果相等,則count++; 下麵貼出代碼: public class Solution { public int ...
  • 這段時間在做項目,發現自己忘得好快呀,幸虧有博客園幫我記著呢,整理博客園簡直不要太重要了哦 因為做的是一個內部管理系統,只用了一個主頁面,所有的都不允許整個網頁刷新,所以我們只能用ajax 來做,當然剛開始做也走了很多的彎路,最終還是做出來了 這點還是比較欣慰的 今天要整理一下ajax實現修改功能 ...
  • 作為一個能安全運行的工具庫,為了保證占用資源的安全性,對異常處理(exception handling)和事後處理(final clean-up)的支持是不可或缺的。FunDA的數據流FDAPipeLine一般是通過讀取資料庫數據形成數據源開始的。為了保證每個數據源都能被安全的使用,FunDA提供了 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...