Python中的Base64编码问题

时间:2018-09-10 09:54:05

标签: python encoding base64 decoding

我需要在python中保存一个params文件,并且此params文件包含一些我不会在纯文本上保留的参数,因此我将整个文件编码为base64(我知道这不是最安全的编码世界,但它适用于我需要使用的那种数据。

使用编码,一切工作正常。我对文件的内容进行编码(带有适当扩展名的简单txt)并保存文件。问题在于解码。我打印了保存文件之前编码的文本和保存文件中编码的文本,它们完全相同,但是由于我不知道的原因,对保存文件的文本进行解码会返回此错误{{1 }},然后在保存文件之前对文本进行解码即可。

有解决此问题的主意吗?

这是我的代码,我尝试将所有内容都转换为字节,字符串以及所有内容...

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8d in position 1: invalid start byte

1 个答案:

答案 0 :(得分:3)

您的错误在于处理bytes返回的base64.b64encode()对象,您在对象上调用了str()

newparams.write(str(paramsencoded))

该{em>不解码 bytes对象:

>>> bytesvalue = b'abc='
>>> str(bytesvalue)
"b'abc='"

请注意b'...'表示法。您生成了bytes对象的 representation ,这是一个包含Python语法的字符串,该字符串可以为调试目的而复制该值(您可以复制该字符串值并将其粘贴到Python中以重新创建相同的{值{1}}。

乍一看可能不太容易,因为bytes否则只会生成带有可打印ASCII字节的输出。

但是您的解码问题是从那里开始的,因为在解码时,从文件读取的值在开始时包含base64.b64encode()个字符。前两个字符被解释为Base64数据 b'是有效的Base64字符,解析器将忽略b

'

请注意输出结果完全不同,因为Base64解码现在从错误的位置开始,因为>>> bytesvalue = b'hello world' >>> base64.b64encode(bytesvalue) b'aGVsbG8gd29ybGQ=' >>> str(base64.b64encode(bytesvalue)) "b'aGVsbG8gd29ybGQ='" >>> base64.b64decode(str(base64.b64encode(bytesvalue))) # with str() b'm\xa1\x95\xb1\xb1\xbc\x81\xdd\xbd\xc9\xb1\x90' >>> base64.b64decode(base64.b64encode(bytesvalue)) # without str() b'hello world' 是第一个字节的前6位(使第一个解码后字节6C,6D,6E或6F字节,因此bmno ASCII)。

您可以正确地解码值(使用pparamsencoded.decode('ascii')),但是您不应将任何这些数据都视为文本。

相反,请以 binary模式打开文件。然后使用str(paramsencoded, 'ascii')对象进行读写操作,并且bytesbase64.b64encode()函数也可以在base64.b64decode()上进行操作,从而实现完美的匹配:

bytes

我明确使用with open('params.bpr', 'rb') as params_source: params = params_source.read() # bytes object params_encoded = base64.b64encode(params) print(params_encoded.decode('ascii')) # base64 data is always ASCII data params_decoded = base64.b64decode(params_encoded) with open('paramsencoded.bpr', 'wb') as new_params: newparams.write(params_encoded) # write binary data with open('paramsencoded.bpr', 'rb') as new_params: params_written = new_params.read() print(params_written.decode('ascii')) # still Base64 data, so decode as ASCII params_decoded = base64.b64decode(params_written) # decode the bytes value print(params_decoded.decode('utf8')) # assuming the original source was UTF-8 而不是bytes.decode(codec)来避免意外的str(..., codec)呼叫。