Мне нужно встроить двоичные данные в файлы XML, поэтому я решил использовать для этого кодировку base85.
У меня есть большой байтовый массив, который заполнен выводом вызовов на struct.pack()
через bytearray.extend(struct.pack(varying_data))
.Затем он сжимается с помощью 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()
) работает, но я думаю, что это действительно не решает проблему, может быть, это не помогает в других случаях?
Спасибо за помощь!