解码Python中的Base64字符串

10

我已提取图像前景色、纹理和边缘映射值的base64字符串,我有一个以下结构的列表:

forecolor=AgCEAg4DUQQCBQQGARMBFQE1AmUB
edge=AfCAFg5iIATCPwTAEIiBFggBDw
forecolor=AgAsAQ0CJAMcDRgOGg8DHQYeBzYBPQ4-DU0ETgNtBm4CfQI

我正在尝试解码这些值,但是收到了错误的填充错误,以下是确切的错误:

Traceback (most recent call last):
  File "ImageVectorData.py", line 44, in <module>
    print "Decoded String: " + decoded.decode('base64', 'strict')
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/base64_codec.py", line 42, in base64_decode
    output = base64.decodestring(input)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/base64.py", line 321, in decodestring
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

这是我的代码:

for item in value:
    print "String before Split: " + item
    if item.split("=")[0] == "forecolor":
        decoded = (item.split("=")[1])
        print "String to be decoded: " + decoded
        print "Decoded String: " + decoded.decode('base64', 'strict')

当第一个forecolor base64字符串被解码时,我看到了一个有趣的输出结果:

这是它的输出:
String before Split: forecolor=AgCEAg4DUQQCBQQGARMBFQE1AmUB
String to be decoded: AgCEAg4DUQQCBQQGARMBFQE1AmUB
Decoded String: ?Q5e

我不太确定我在这里做错了什么。我查看了下面的Python文档并尝试了一下,但那也不起作用: http://docs.python.org/library/base64.html


edge的值似乎不是一个有效的base64编码字符串,因此Python会给出错误消息。使用有效的输入,一切都应该正常工作。 - Sven Marnach
如果您查看代码,我只是尝试解码前景色,因此我不认为边缘在这一点上起作用。 - add-semi-colons
@SvenMarnach,您可以通过在字符串末尾添加几个==来解决填充问题。更大的问题是,解码结果完全无法理解。 - Mark Ransom
1
正如其他人指出的那样 - 问题在于您的输入数据。我们对此无能为力...垃圾进,垃圾出。 - tMC
1个回答

8
您正在尝试解码没有填充的Base64字符串。虽然许多Base64编码方式没有填充,但Python要求标准的Base64解码需要填充。这个StackOverflow问题有更深入的解释:Python: Ignore 'Incorrect padding' error when base64 decoding 对于您的代码,我建议进行类似以下的修改:
for item in value:
    print "String before Split: " + item
    if item.split("=")[0] == "forecolor":
        decoded = (item.split("=")[1])
        print "String to be decoded: " + decoded
        # Add Padding if needed
        decoded += "===" # Add extra padding if needed
        print "Decoded String: " + decoded.decode('base64', 'strict')

根据您的评论,似乎您还需要将base64解码后返回的字节数组转换为整数列表。我假设这些整数是小端短整数。

import struct
x = "AgAsAQ0CJAMcDRgOGg8DHQYeBzYBPQ4-DU0ETgNtBm4CfQI"
x += "==="
y = x.decode('base64', 'strict')
intList = [struct.unpack('<h', y[i] + y[i+1]) for i in xrange(0, len(y), 2)]
print intList

结果是:
[(2,), (300,), (525,), (804,), (3356,), (3608,), (3866,), (7427,), (7686,), (13831,), (15617,), (782,), (16723,), (-32749,), (16859,), (-32613,), (16543,)]

我仍然得到相同的错误,我使用了你放置的确切行。 - add-semi-colons
1
我在另一个答案中发现了另一种适用于您的数据的技术。我已经更新了答案。它只是添加足够的填充以涵盖所有情况。 - Jesse Harris
谢谢,但问题是解码后的值应该是像2、3、4、5这样的向量,而不是像d#CSs这样的字符串,填充问题已经解决,但数据完全错误。这些编码值是由C++程序生成的,你认为这与此有关吗? - add-semi-colons
我已经附加了我的答案,将字节数组转换为整数列表。如果base64部分正常工作,我建议关闭此问题并打开另一个涉及字节数组的问题。 - Jesse Harris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接