base85编码字符串解码时出现base85溢出错误
base85 overflow error during decoding of base85 encoded string
我需要将二进制数据嵌入到 XML 文件中,因此我选择为此使用 base85 编码。
我有一个很大的字节数组,里面装满了通过 bytearray.extend(struct.pack(varying_data))
调用 struct.pack()
的输出。然后用 zlib
压缩并用 base64.b85encode()
.
编码
这一直有效,但在单个输入文件上,出现以下奇怪错误:
ValueError: base85 overflow in hunk starting at byte 582200`
然后我修改了 base64.py 以打印出当前块具有的值以及它由哪些字节组成。输入块为 b'||a|3'
,其值为 4.331.076.573,大于 256^4 = 4.294.967.296,因此不能用四个字节表示(这就是错误的来源)。
但是我不明白的是:怎么会这样?
这是代码的重要部分:
elif isinstance(self.content, (bytes, bytearray)):
base85 = zlib.compress(self.content, 9)
# pad=False doesn't make a difference here
base85 = base64.b85encode(base85, pad=True).decode()
base85 = escape_xml(base85)
file.write(base85)
def escape_xml(text):
text = text.replace("&", "&")
text = text.replace("<", "<")
text = text.replace(">", ">")
text = text.replace("\"", """)
text = text.replace("'", "'")
return text
解码代码:
def decode_binary_data(data):
data = unescape_xml(data)
# Remove newline for mixed content support (does not apply in this case)
data = data.split("\n", 1)[0]
# Error!
data = base64.b85decode(data)
return zlib.decompress(data)
def unescape_xml(text):
text = text.replace(""", "\"")
text = text.replace("'", "'")
text = text.replace("<", "<")
text = text.replace(">", ">")
text = text.replace("&", "&")
return text
Base85 理论上可以与 85^5 = 4.437.053.125 可能的组合一起使用,但是当它从字节获取输入时,我想知道这怎么可能。这是来自压缩吗?这不应该是问题,因为编码和解码应该是对称的。如果是问题,如何压缩数据?
改为选择 Ascii85 (a84encode()
) 可行,但我认为这并不能真正解决问题,也许在其他情况下会失败?
感谢您的帮助!
我找到问题了! base85 算法和压缩都不是这里的问题。就是 XML.
对于 exporting/writing 包含 base85 字符串的 XML,我编写了自己的 class 和导出 XML 的函数,这样它看起来很漂亮(xml.etree.ElementTree
将所有内容写入一行,对于这个项目,我不能使用来自 pip 的外部包)。这就是必须手动转义 base85 字符串的原因。
但是为了读取 XML 个文件,我使用 xml.etree.ElementTree
。 我不知道大多数 XML 库会自动 (un) 转义字符串(这是有道理的)。
所以,问题出在手动反转义上,ElementTree
是自动进行的。结果,base85 字符串未转义 两次 。由于 base85 字母表包含 XML 转义字符串($amp;
、$lt;
等)中包含的每个字母,并且该 base85 字符串中有超过 500.000 个字符,因此很可能存在是输出字符串中的字符组合,形成有效的 XML 转义字符串。
这就是问题所在。 <
包含在未转义的 base85 字符串中并再次被转义,导致所有后续字节的偏移量导致此错误。
我经常使用 LabView、Python 和 javascript,并且不得不为 LabView 创建我自己的 Base85 编码和解码例程,它只有 MD5 校验和。对于加密或良好的混淆,您必须自己动手。也许未来版本的 LabView 会在库中包含 Base85。
我要表达的意思是我现在拥有 base85 的所有 3 种风格。 Ascii85、Base85 和 Z85。每个都有一个唯一的字符集,它在从 base10 转换为 base85 时使用。 每个版本都可能被诸如控制字符、连续 space 字符过多、HTML 和 XML 之类的符号繁重的东西等问题绊倒(损坏的输出) , 超过 126 个字符(波浪号)。
为了安全地编码大型文本文件,尤其是多行和符号较多的文件,我只是让代码感知所有这些潜在的问题并首先转换为十六进制。是的,它使字符数加倍,但 base10 到 base85 引擎不会崩溃。即使对于大型纯文本文件,Z85 也会在 1000 个字符左右后崩溃,问题在于 Z85 字符映射,它的符号是乱码的,因此在长字符串上会发生溢出。为了我自己的目的,我更改了 Z85 字符映射,使符号按十进制顺序排列,现在 Z85 不再在大文件上崩溃。
Ascii85、Base85 和 Z85 会因上述相同问题而崩溃,无论是用 python、javascript 还是 LabView 编写。 通常是多个连续的 symbols/spaces 导致数学溢出, 因此输出已损坏且无法解码。
注意:填充字符串非常重要 可以被 4 整除,解码时用 'u' 或波浪号填充哈希字符串,这样hash 可以被 5 整除。
我需要将二进制数据嵌入到 XML 文件中,因此我选择为此使用 base85 编码。
我有一个很大的字节数组,里面装满了通过 bytearray.extend(struct.pack(varying_data))
调用 struct.pack()
的输出。然后用 zlib
压缩并用 base64.b85encode()
.
这一直有效,但在单个输入文件上,出现以下奇怪错误:
ValueError: base85 overflow in hunk starting at byte 582200`
然后我修改了 base64.py 以打印出当前块具有的值以及它由哪些字节组成。输入块为 b'||a|3'
,其值为 4.331.076.573,大于 256^4 = 4.294.967.296,因此不能用四个字节表示(这就是错误的来源)。
但是我不明白的是:怎么会这样?
这是代码的重要部分:
elif isinstance(self.content, (bytes, bytearray)):
base85 = zlib.compress(self.content, 9)
# pad=False doesn't make a difference here
base85 = base64.b85encode(base85, pad=True).decode()
base85 = escape_xml(base85)
file.write(base85)
def escape_xml(text):
text = text.replace("&", "&")
text = text.replace("<", "<")
text = text.replace(">", ">")
text = text.replace("\"", """)
text = text.replace("'", "'")
return text
解码代码:
def decode_binary_data(data):
data = unescape_xml(data)
# Remove newline for mixed content support (does not apply in this case)
data = data.split("\n", 1)[0]
# Error!
data = base64.b85decode(data)
return zlib.decompress(data)
def unescape_xml(text):
text = text.replace(""", "\"")
text = text.replace("'", "'")
text = text.replace("<", "<")
text = text.replace(">", ">")
text = text.replace("&", "&")
return text
Base85 理论上可以与 85^5 = 4.437.053.125 可能的组合一起使用,但是当它从字节获取输入时,我想知道这怎么可能。这是来自压缩吗?这不应该是问题,因为编码和解码应该是对称的。如果是问题,如何压缩数据?
改为选择 Ascii85 (a84encode()
) 可行,但我认为这并不能真正解决问题,也许在其他情况下会失败?
感谢您的帮助!
我找到问题了! base85 算法和压缩都不是这里的问题。就是 XML.
对于 exporting/writing 包含 base85 字符串的 XML,我编写了自己的 class 和导出 XML 的函数,这样它看起来很漂亮(xml.etree.ElementTree
将所有内容写入一行,对于这个项目,我不能使用来自 pip 的外部包)。这就是必须手动转义 base85 字符串的原因。
但是为了读取 XML 个文件,我使用 xml.etree.ElementTree
。 我不知道大多数 XML 库会自动 (un) 转义字符串(这是有道理的)。
所以,问题出在手动反转义上,ElementTree
是自动进行的。结果,base85 字符串未转义 两次 。由于 base85 字母表包含 XML 转义字符串($amp;
、$lt;
等)中包含的每个字母,并且该 base85 字符串中有超过 500.000 个字符,因此很可能存在是输出字符串中的字符组合,形成有效的 XML 转义字符串。
这就是问题所在。 <
包含在未转义的 base85 字符串中并再次被转义,导致所有后续字节的偏移量导致此错误。
我经常使用 LabView、Python 和 javascript,并且不得不为 LabView 创建我自己的 Base85 编码和解码例程,它只有 MD5 校验和。对于加密或良好的混淆,您必须自己动手。也许未来版本的 LabView 会在库中包含 Base85。
我要表达的意思是我现在拥有 base85 的所有 3 种风格。 Ascii85、Base85 和 Z85。每个都有一个唯一的字符集,它在从 base10 转换为 base85 时使用。 每个版本都可能被诸如控制字符、连续 space 字符过多、HTML 和 XML 之类的符号繁重的东西等问题绊倒(损坏的输出) , 超过 126 个字符(波浪号)。
为了安全地编码大型文本文件,尤其是多行和符号较多的文件,我只是让代码感知所有这些潜在的问题并首先转换为十六进制。是的,它使字符数加倍,但 base10 到 base85 引擎不会崩溃。即使对于大型纯文本文件,Z85 也会在 1000 个字符左右后崩溃,问题在于 Z85 字符映射,它的符号是乱码的,因此在长字符串上会发生溢出。为了我自己的目的,我更改了 Z85 字符映射,使符号按十进制顺序排列,现在 Z85 不再在大文件上崩溃。
Ascii85、Base85 和 Z85 会因上述相同问题而崩溃,无论是用 python、javascript 还是 LabView 编写。 通常是多个连续的 symbols/spaces 导致数学溢出, 因此输出已损坏且无法解码。
注意:填充字符串非常重要 可以被 4 整除,解码时用 'u' 或波浪号填充哈希字符串,这样hash 可以被 5 整除。