[英]Python base64 encoding a list
Encoding is new to me in Python, and I am trying to understand it. 编码对我来说是Python的新手,我正在尝试理解它。 Apologies if this has been asked and answered already.
抱歉,是否已被要求和回答。
I am trying to encode a Python list and decode it. 我正在尝试对Python列表进行编码并对其进行解码。 When I am trying to encode a list directly, I am hitting an error like below.
当我尝试直接对列表进行编码时,遇到如下错误。
>>> my_list = [1, 2, 3]
>>> encoded_list = base64.b64encode(my_list)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/base64.py", line 54, in b64encode
encoded = binascii.b2a_base64(s)[:-1]
TypeError: b2a_base64() argument 1 must be string or buffer, not list
To fix it, I converted the list object to a string and passed it to the encode function and I was able to successfully encode it. 为了解决这个问题,我将列表对象转换为字符串,然后将其传递给encode函数,从而能够成功对其进行编码。
>>> encoded_list = base64.b64encode(str(my_list))
>>> encoded_list
'WzEsIDIsIDNd'
When I try to decode it, I get a decoded string like below. 当我尝试对其进行解码时,会得到如下所示的解码字符串。
>>> decoded_list = base64.b64decode(encoded_list)
>>> decoded_list
'[1, 2, 3]'
>>> type(decoded_list)
<type 'str'>
But my original intention was to encode and decode a list and not convert the list to a string and then string to list. 但是我的初衷是对列表进行编码和解码,而不是将列表转换为字符串,然后再将字符串转换为列表。
Pretty sure this is not the right way to encode objects like dict or a list. 可以肯定的是,这不是编码诸如dict或列表之类的对象的正确方法。 If that's the case, Can someone please enlighten me on how to encode/decode non string objects in Python?
如果是这样,有人可以启发我如何在Python中编码/解码非字符串对象吗?
Thanks very much. 非常感谢。
Try encoding/decoding using JSON instead of string. 尝试使用JSON而不是字符串进行编码/解码。
import json
import base64
my_list = [1, 2, 3]
json_encoded_list = json.dumps(my_list)
#: '[1, 2, 3]'
b64_encoded_list = base64.b64encode(json_encoded_list)
#: 'WzEsIDIsIDNd'
decoded_list = base64.b64decode(b64_encoded_list)
#: '[1, 2, 3]'
my_list_again = json.loads(decoded_list)
#: [1, 2, 3]
But in practice, for pretty much any storage reasons I can think of there's no real reason to base64 encode your json output. 但实际上,出于几乎任何存储原因,我都可以想到没有真正的理由对base64编码json输出进行编码。 Just encode and decode to json.
只需编码和解码为json。
my_list = [1, 2, 3]
json_encoded_list = json.dumps(my_list)
#: '[1, 2, 3]'
my_list_again = json.loads(json_encoded_list)
#: [1, 2, 3]
If you need anything more complicated than Arrays and Dictionaries, then probably go with 7stud's pickle method. 如果您需要比数组和字典更复杂的东西,则可以使用7stud的pickle方法。 However JSON is simple, readable, widely supported and cross-compatible with other languages.
但是,JSON是简单,易读,广泛支持的并且与其他语言交叉兼容。 I'd choose it whenever possible.
我会尽可能选择它。
You are interested in the data being encoded not the list itself being encoded. 您对正在编码的数据感兴趣,而不是对列表本身进行编码。 Therefore I suggest the following: use
struct
to pack the data. 因此,我建议以下内容:使用
struct
打包数据。
x = range(10)
import struct
y = struct.pack('<{}i'.format(len(x)), *x)
import base64
z = base64.b64encode(y)
z will now be an encoding of the data in the list. z现在将成为列表中数据的编码。
You can decode it back and retrieve the list as follows: 您可以将其解码回去并检索列表,如下所示:
y = base64.b64decode(z)
list(struct.unpack('<{}i'.format(len(y)/4), y))
The error is pretty self explanatory: 该错误很容易说明:
b2a_base64() argument 1 must be string or buffer, not list
b2a_base64()参数1必须是字符串或缓冲区,而不是列表
How about calling an encoding method that will take a list? 如何调用将采用列表的编码方法?
import pickle
data = [
1,
"hello",
{
'a': [1, 2.0, 3, 4+6j],
'b': ("character string", b"byte string"),
'c': set([None, True, False])
}
]
#Write encoded string to a file:
with open('data.pickle', 'wb') as f:
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
#Read encoded string from file:
with open('data.pickle', 'rb') as f:
print(f.read()) #Display the encoded string.
f.seek(0)
data = pickle.load(f)
print(data)
print(data[2]['a']) #Show that data is actually a python list.
--output:--
b'\x80\x04\x95\x87\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01\x8c\x05hello\x94}\x94(\x8c\x01a\x94]\x94(K\x01G@\x00\x00\x00\x00\x00\x00\x00K\x03\x8c\x08builtins\x94\x8c\x07complex\x94\x93\x94G@\x10\x00\x00\x00\x00\x00\x00G@\x18\x00\x00\x00\x00\x00\x00\x86\x94R\x94e\x8c\x01c\x94\x8f\x94(\x89\x88N\x90\x8c\x01b\x94\x8c\x10character string\x94C\x0bbyte string\x94\x86\x94ue.'
[1, 'hello', {'a': [1, 2.0, 3, (4+6j)], 'c': {False, True, None}, 'b': ('character string', b'byte string')}]
[1, 2.0, 3, (4+6j)]
And, if you want to work base64 encoding into the mix: 而且,如果您想将base64编码用于混合:
import pickle
import base64
data = [
1,
"hello",
{
'a': [1, 2.0, 3, 4+6j],
'b': ("character string", b"byte string"),
'c': set([None, True, False])
}
]
pstr = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
bstr = base64.b64encode(pstr)
print(pstr)
print(bstr)
--output:--
b'\x80\x04\x95\x87\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01\x8c\x05hello\x94}\x94(\x8c\x01b\x94\x8c\x10character string\x94C\x0bbyte string\x94\x86\x94\x8c\x01c\x94\x8f\x94(\x89\x88N\x90\x8c\x01a\x94]\x94(K\x01G@\x00\x00\x00\x00\x00\x00\x00K\x03\x8c\x08builtins\x94\x8c\x07complex\x94\x93\x94G@\x10\x00\x00\x00\x00\x00\x00G@\x18\x00\x00\x00\x00\x00\x00\x86\x94R\x94eue.'
b'gASVhwAAAAAAAABdlChLAYwFaGVsbG+UfZQojAFilIwQY2hhcmFjdGVyIHN0cmluZ5RDC2J5dGUgc3RyaW5nlIaUjAFjlI+UKImITpCMAWGUXZQoSwFHQAAAAAAAAABLA4wIYnVpbHRpbnOUjAdjb21wbGV4lJOUR0AQAAAAAAAAR0AYAAAAAAAAhpRSlGV1ZS4='
pstr = base64.b64decode(bstr)
print(pstr)
new_data = pickle.loads(pstr)
print(new_data[2]['a'][0])
--output:--
----------------(compare to previous pstr)
b'\x80\x04\x95\x87\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01\x8c\x05hello\x94}\x94(\x8c\x01b\x94\x8c\x10character string\x94C\x0bbyte string\x94\x86\x94\x8c\x01a\x94]\x94(K\x01G@\x00\x00\x00\x00\x00\x00\x00K\x03\x8c\x08builtins\x94\x8c\x07complex\x94\x93\x94G@\x10\x00\x00\x00\x00\x00\x00G@\x18\x00\x00\x00\x00\x00\x00\x86\x94R\x94e\x8c\x01c\x94\x8f\x94(\x89\x88N\x90ue.'
1
Or, you can use eval(), gulp, to evaluate a string: 或者,您可以使用gulp eval()来评估字符串:
mystr = '''
[
1,
"hello",
{
'a': [1, 2.0, 3, 4+6j],
'b': ("character string", b"byte string"),
'c': set([None, True, False])
}
]
'''
mylist = eval(mystr)
print(mylist[0])
--output:--
1
So, you could stringify your list, base64 encode the string, then base64 unencode the string, then eval the string to get the original list back. 因此,您可以对列表进行字符串化,对字符串进行base64编码,然后对字符串进行base64取消编码,然后对字符串进行评估以获取原始列表。 Because eval can execute arbitrary code in a string, like a command to delete your hard drive, you don't want to eval untrusted strings.
因为eval可以执行字符串中的任意代码(例如删除硬盘驱动器的命令),所以您不想评估不可信的字符串。 Although, the docs for the pickle module contain similar warnings.
虽然,pickle模块的文档包含类似的警告。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.