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)
调用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)