使用 Base64 和 Pickle 进行编码和解码

Mar*_*tik 2 python base64 pickle

我需要pickle一个字典,然后在通过API调用传输数据之前对其进行Base64编码。

接收器应该解码 Base64 数据,并且 pickle 将其加载回正确的字典中。

问题是它在解码时失败,解码 Base64 数据后它似乎不是相同的二进制数据,因此 Pickle 失败。

我缺少什么?

import pickle
import base64
import json

def publishData():
   testDict = {}
   testDict['testKey1'] = [1,2,3]
   testDict['testKey2'] = [4,5,6]
   #Dump the dict to pickle file
   with open("test.pkl","wb") as f:
      pickle.dump(testDict, f)
   #Read the pickle
   with open("test.pkl", "rb") as openfile:
      data = openfile.read() #Read the raw pickle (binary)
   print("publishData - Pickle read : {}".format(data))
   #Base64 encode it to ensure formatting in JSON
   data = base64.b64encode(data)
   print("publishData - Base64 encoded : {}".format(data))
   #Create a json to be published via API
   publishJson = json.dumps({"payload":str(data)})
   print("publishData - Publish JSON : {}".format(publishJson))
   #Decode the data
   decodeData(publishJson)

def decodeData(publishJson):
   data = json.loads(publishJson)
   payload = data['payload']
   payload = base64.b64decode(payload)
   print("decodeData - Payload decoded: {}".format(payload))
   print(pickle.loads(payload))

if __name__ == "__main__":
   publishData()
Run Code Online (Sandbox Code Playgroud)

输出:

publishData - Pickle read : b'\x80\x04\x95/\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x08testKey1\x94]\x94(K\x01K\x02K\x03e\x8c\x08testKey2\x94]\x94(K\x04K\x05K\x06eu.'
publishData - Base64 encoded : b'gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg=='
publishData - Publish JSON : {"payload": "b'gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg=='"}
decodeData - Payload decoded: b'n\x00\x12T\xbc\x00\x00\x00\x00\x00\x00\x01\xf6P\xa20!\xd1\x95\xcd\xd1-\x95\xe4\xc6QvP\xa1,\x05,\t,\r\x960!\xd1\x95\xcd\xd1-\x95\xe4\xcaQvP\xa1,\x11,\x15,\x19\x95\xd4\xb8'

_pickle.UnpicklingError: invalid load key, 'n'.
Run Code Online (Sandbox Code Playgroud)

aar*_*ron 5

调用data.decode()或等效方法str(data, encoding='utf-8')将字节转换为有效的 base64 编码字符串:

# publishJson = json.dumps({"payload": str(data)})     # -
publishJson = json.dumps({"payload": data.decode())})  # +
Run Code Online (Sandbox Code Playgroud)

来自https://docs.python.org/3/library/stdtypes.html#str

不带或参数传递bytes对象属于返回非正式字符串表示的第一种情况str()encodingerrors

print(data)                 #  b'gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg=='
print(repr(data))           #  b'gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg=='

print(str(data))            #  b'gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg=='
print(repr(str(data)))      # "b'gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg=='"

print(data.decode())        #    gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg==
print(repr(data.decode()))  #   'gASVLwAAAAAAAAB9lCiMCHRlc3RLZXkxlF2UKEsBSwJLA2WMCHRlc3RLZXkylF2UKEsESwVLBmV1Lg=='
Run Code Online (Sandbox Code Playgroud)