[摘要] 對 Base64 編碼的簡介,常用場景舉例,編、解碼流程,以及如何在 Python 中使用 Base64編碼與解碼 ...
0x00 Base64簡介
0x01 常用場景舉例
0x02 編、解碼流程
0x03 Python中Base64編碼與解碼
0x00 Base64簡介
我們知道在電腦中任何數據都是按ascii碼存儲的,而ascii碼的128~255之間的值是不可見字元。而在網路上交換數據時,比如說從A地傳到B地,往往要經過多個路由設備,由於不同的設備對字元的處理方式有一些不同,這樣那些不可見字元就有可能被處理錯誤,這是不利於傳輸的。所以就先把數據先做一個Base64編碼,統統變成可見字元,這樣出錯的可能性就大降低了。
此處摘自:https://www.zhihu.com/question/36306744/answer/71626823
編碼取值範圍:大寫字母(A-Z),小寫字母(a-z),數字(0-9),特殊字元:'+' 和 '/' 一共64個字元。
0x01 常用場景舉例
舉例1 :Base64編碼最常見於郵件與網頁傳輸中,比如QQ郵箱查看郵件原文就看到郵件原文中的 Content-Transfer-Encoding:base64,郵件最結尾便是base64編碼後的內容,比如:
Content-Type:text/html; charset="UTF-8" Content-Transfer-Encoding:base64 X-SMTPAPI: List-Unsubscribe:<http://sctrack.sendcloud.net/track/unsubscribe.do?p=eyJ1c2VTk1%3D> 5oKo5Zyo5Y2a5a6i5Zut5L2/55So5LqG5a+G56CB6YeN572u5Yqf6IO9LCDor7fpgJrov4fkuIvp naLnmoTlnLDlnYDkv67mlLnlr4bnoIE6PGJyLz48YSBocmVmPSJodHRwczovL3Bhc3Nwb3J0LmNu YmxvZ3MuY29tL1Jlc2V0U******dvcmQuYXNweD9pZD1mOGIyMzUwMDUwNDM0YzAwYjU2MDZkOWMz ZTY0MTZkYzIwMTcxMDIxMTgwMjU5ODgxMTkzODIyMjQ2*****+***HM6Ly9wYXNzcG9ydC5jbmJs b2dzLmNvbS9SZXNldFBhc3N3b3JkLmFzcHg/aWQ9ZjhiMjM1MDA1MDQzNGMwMGI1NjA2ZDljM2U2 NDE2ZGMyMDE3MTAyMTE4MDI1OTg4MTE5MzgyMjI0NjE8L2E+PGJyLz4=
郵件原文:
您在博客園使用了密碼重置功能, 請通過下麵的地址修改密碼:
https://passport.cnblogs.com/ResetPassword.aspx?id=f8b23500******00b5606d9c3e6416dc201710211802598811938222461
舉例2:網站 http://pythontutor.com/visualize.html#mode=edit,在網頁傳輸中就使用了base64編碼傳輸圖片數據:
此處網頁協議傳輸中就使用了base64來傳輸圖片數據,圖片數據原文:
GIF89a!,L;
0x02 編、解碼流程
Base64索引表:
數值 | 字元 | 數值 | 字元 | 數值 | 字元 | 數值 | 字元 | |||
---|---|---|---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w | |||
1 | B | 17 | R | 33 | h | 49 | x | |||
2 | C | 18 | S | 34 | i | 50 | y | |||
3 | D | 19 | T | 35 | j | 51 | z | |||
4 | E | 20 | U | 36 | k | 52 | 0 | |||
5 | F | 21 | V | 37 | l | 53 | 1 | |||
6 | G | 22 | W | 38 | m | 54 | 2 | |||
7 | H | 23 | X | 39 | n | 55 | 3 | |||
8 | I | 24 | Y | 40 | o | 56 | 4 | |||
9 | J | 25 | Z | 41 | p | 57 | 5 | |||
10 | K | 26 | a | 42 | q | 58 | 6 | |||
11 | L | 27 | b | 43 | r | 59 | 7 | |||
12 | M | 28 | c | 44 | s | 60 | 8 | |||
13 | N | 29 | d | 45 | t | 61 | 9 | |||
14 | O | 30 | e | 46 | u | 62 | + | |||
15 | P | 31 | f | 47 | v | 63 | / |
這裡用兩個字母 'ab' 來分析base64 詳細的編碼流程:
文本 | a | b | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ASCII編碼 | 97 | 98 | ||||||||||||||||||||||
二進位位 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | ||||||||
索引 | 24 | 22 | 8 | |||||||||||||||||||||
Base64編碼 | Y | W | I | = |
編碼後: YWI=
編碼流程:
- base64 將兩個位元組的 'ab ' 看做是3個位元組的文本數據
- 將 'a' 和 'b' 通過ASCII碼轉為10進位,為別是 97、98、0(補1個0)
- 將10進位再轉換為2進位,分別對應:01100001、01100010、00000000
- 將3個8位的2進位按每6位分割為4個6位的2進位,分割後:011000、010110、001000 (0010尾部補0湊足6位)
- 將3個有效的6位2進位轉為10進位,即base64編碼標的索引號,分別對應:24,22,8
- 依次將3個10進位的索引號轉為對應的字元,便是編碼結果:Y、W、I
- 但是只返回了3個位元組的編碼結果,所以補上去一個空位元組,最終用 '=' 填補上空位,最終組合成4位元組字元:YWI=
文本字元 --> 十進位 --> 二進位 --> 每6位切割 --> 切割後的值轉為10進位(索引值) --> 轉字元
ipython 下測試編碼字母 'a':
In [9]: ord('a') Out[9]: 97 In [10]: bin(97) Out[10]: '0b1100001' In [11]: '{:>08b}'.format(97) #轉2進位 Out[11]: '01100001' In [12]: int('00011000',2) #取前6位前面補0再轉位10進位,即是base64表索引值24對應字元: Y Out[12]: 24
解碼流程:
編碼 --> 轉為base64索引值 --> 索引值轉6位的2進位 --> 每8位切割轉2進位 --> 轉10進位 --> 轉原文本
0x03 Python中Base64編碼與解碼
需要導入python 的 base64 庫
在python 3 以上版本中需要將字元轉位bytes類型,再對其編碼或解碼
In [1]: import base64
In [2]: str = 'ab'
In [3]: base64.b64encode(str.encode())
Out[3]: b'YWI='
In [4]: str2 = b'YWI='
In [5]: base64.b64decode(str2.decode())
Out[5]: b'ab'
In [6]: base64.b64decode(str2.decode()).decode()
Out[6]: 'ab'
總結:
藉助base64編碼又回顧了一下 ascii 、2進位、10進位、16進位,對電腦之間和網路數據傳輸又增深了瞭解,對之後的網路編程課程部分有很大的幫助。