简体   繁体   English

Python base64编码列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM