python學習筆記---python3中Base64編碼時參數不能為str


base64

原理

base64就是對二進制數據進行編碼,比如我有6字節的二進制數據,然后每3個字節分為一組,也就是一組有3*8 = 24bit(1個字節由8位二進制數組成) ,然后把這個 24bit 分為4組,也就是每一組有6個bit。其實說白了base64就是將二進制數據每6個bit分為一組,6個bit就是6位二進制的數,最大的是111111,對應十進制就是63,也就是6位二進制數能夠表示 0~63個字符。

比如 6位二進制數是111111 那么對應的就是 /  ,就會將 / 最終返回給我們 

 

如果要編碼的二進制數據不是3的倍數,最后會剩下1個或2個字節怎么辦?此時,需在原數據后面添加1個或2個零值字節,使其字節數是3的倍數。然后,在編碼后的字符串后面添加1個或2個等號“=”,表示所添加的零值字節數。解碼的時候,會自動去掉。

優點:可以將二進制數據轉換成可打印字符,方便傳輸數據;對數據進行簡單的加密,肉眼安全。

缺點:內容編碼后的體積會變大,編碼和解碼需要額外的工作量。

它的使用場景有很多,比如將圖片等資源文件以Base64編碼形式直接放於代碼中,使用的時候反Base64后轉換成Image對象使用;有些文本協議不支持不可見字符的傳遞,只能轉換成可見字符來傳遞信息。有時在一些特殊的場合,大多數消息是純文本的,偶爾需要用這條純文本通道傳一張圖片之類的情況發生的時候,就會用到Base64,比如多功能Internet 郵件擴充服務(MIME)就是用Base64對郵件的附件進行編碼的。

下面用法報錯:


# 錯誤示例
import base64
s = '我是字符串'
a = base64.b64encode(s) # 3.0版本以上 不允許接收 str 為參數 必須為byte

 

Traceback (most recent call last):
  File "<pyshell#70>", line 1, in <module>
  a = base64.b64encode(s)
  File "D:\工作軟件\python\lib\base64.py", line 58, in b64encode
  encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'

 

正確用法:

>>> import base64
>>> s = '我是字符串'
 
# 先進行編碼 轉換為字節
>>> s = s.encode() # 默認是utf8
>>> s     # byte類型數據以16進制來表示
b'\xe6\x88\x91\xe6\x98\xaf\xe5\xad\x97\xe7\xac\xa6\xe4\xb8\xb2'
>>> a = base64.b64encode(s) # 在編碼時會自動將16進制轉換為2進制,然后每6bit一組,再找到對應的字符
>>> a
b'5oiR5piv5a2X56ym5Liy'
>>> base64.b64decode(b'5oiR5piv5a2X56ym5Liy').decode('utf8') 
'我是字符串'
 
 
# 轉成其他編碼也是可以的
>>> s = s.encode('gbk')
>>> s
b'\xce\xd2\xca\xc7\xd7\xd6\xb7\xfb\xb4\xae'
>>> a = base64.b64encode(s)
>>> a
b'ztLKx9fWt/u0rg=='
>>> base64.b64decode(b'ztLKx9fWt/u0rg==').decode('gbk')                         
'我是字符串'

 

由於標准的Base64編碼后可能出現字符+/,在URL中就不能直接作為參數,所以又有一種"url safe"的base64編碼,其實就是把字符+/分別變成-_

>>> base64.b64encode(b'i\xb7\x1d\xfb\xef\xff')
b'abcd++//'
>>> base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff')
b'abcd--__'
>>> base64.urlsafe_b64decode('abcd--__')
b'i\xb7\x1d\xfb\xef\xff'

 

還可以自己定義64個字符的排列順序,這樣就可以自定義Base64編碼,不過,通常情況下完全沒有必要。

Base64是一種通過查表的編碼方法,不能用於加密,即使使用自定義的編碼表也不行。

Base64適用於小段內容的編碼,比如數字證書簽名、Cookie的內容等。

由於=字符也可能出現在Base64編碼中,但=用在URL、Cookie里面會造成歧義,所以,很多Base64編碼后會把=去掉:

去掉=后怎么解碼呢?因為Base64是把3個字節變為4個字節,所以,Base64編碼的長度永遠是4的倍數,因此,需要加上=把Base64字符串的長度變為4的倍數,就可以正常解碼了。

如下:

import base64
 
def base64encode(raw):
    return base64.urlsafe_b64encode(raw).strip("=")
 
def base64decode(data):
    return base64.urlsafe_b64decode(data + "=" * (-len(data)%4))

 

————————————————
版權聲明:本文為CSDN博主「苝花向暖丨楠枝向寒」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_40247263/java/article/details/82423051

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM