【问题标题】:Compress in Java, decompress in Python?在 Java 中压缩,在 Python 中解压缩?
【发布时间】:2016-10-25 18:23:26
【问题描述】:

我正在尝试在我的 Android 应用程序 (Java) 中压缩一个字符串,然后在服务器上使用 Python 解压缩它。我尝试使用 Inflater 类,但随后在 python 端出现“错误:解压缩数据时错误 -3:不正确的标头检查”。在python方面,我是使用zlib来解压的:

data_string = zlib.decompress(compressed_string)

在Android端,我们使用Deflater进行压缩:

String stringData = commentData == null ? sleepData.toString() : sleepData.toString() + commentData.toString();

byte[] bytes = stringData.getBytes("UTF-8");
int length = bytes.length;
Deflater deflater = new Deflater();
deflater.setInput(bytes);
deflater.finish();
byte[] compressedBytes = new byte[length];
deflater.deflate(compressedBytes);
deflater.end();

如何在 python 中解压应用发送的字符串?

谢谢!

编辑: 这是我们从 Android 发送并输入解压缩命令的内容:(点代表更多相同的内容 - 有很多零,最后是一些“0b”:“78efbfbdefbfbdefbfbdefbfbd6e1b2....efbfbd190000000. ....0000‌​000000000b0b0b0b0b0b‌​0b0b0b0b0b

我们尝试过的事情:

-- data_string = zlib.decompress(decrypted,-zlib.MAX_WBITS),它给出了一个新的错误:“Error -3 while decompressing data: invalid stored block lengths”

-- data_string = zlib.decompressobj(decrypted,15+32) 和 data_string = zlib.decompress(compressed_string, 16+zlib.MAX_WBITS) 都给出初始错误“无效的标头检查”。

【问题讨论】:

  • 如何将数据从 Android/Java 端发送到 Server/Python 端?
  • 应该可以,因为Deflater 默认生成 zlib 格式,而zlib.decompress() 默认需要 zlib 格式。您能否以十六进制提供您要提供给zlib.decompress() 的内容的前几个字节?
  • 这就是字符串的样子:(点表示更多相同 - 有很多零,最后是一些“0b”:“78efbfbdefbfbdefbfbdefbfbd6e1b2....efbfbd190000000. ....0000000000000b0b0b0b0b0b0b0b0b0b0b"
  • 关于数据的发送——我们先压缩,然后在Android端用AES256加密,然后发送到服务器,在那里我们解密,然后尝试解压。在我们添加压缩之前,加密/解密部分工作正常。

标签: java android python zlib compression


【解决方案1】:

添加16+zlib.MAX_WBITS15 + 32 作为第二个[可选] wbits arg in decompress: https://docs.python.org/2/library/zlib.html#zlib.decompress

data_string = zlib.decompress(compressed_string, 16+zlib.MAX_WBITS)

编辑: 根据您将压缩字节传递给 Python 的方式,您的问题可能在于 Python 如何读取压缩字节。

我建议在 Java 中对压缩字节使用 Base64 编码,然后在 Python 中解码 base64,然后以这种方式解压缩这些字节...

Java:

String inputString = "blahblahblah";
byte[] input = inputString.getBytes("UTF-8");

// Compress the bytes
byte[] output = new byte[100];
Deflater compresser = new Deflater();
compresser.setInput(input);
compresser.finish();
int compressedDataLength = compresser.deflate(output);
compresser.end();
System.out.println(Base64.getEncoder().encodeToString(output)); 

Python:

import base64
import zlib
base64_binary = b"eJxLyknMSIJiAB8CBMYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
deflate_bytes=base64.decodebytes(base64_binary)
zlib.decompress(deflate_bytes)
# b'blahblahblah'

相关:

How can I decompress a gzip stream with zlib?

Python decompressing gzip chunk-by-chunk

Byte Array in Python

【讨论】:

  • 感谢您的回答!添加 16+zlib.MAX_WBITS 或 15 + 32 作为选项参数不起作用。它给出了同样的错误。
  • 顺便说一句,我们还尝试了“data_string = zlib.decompress(decrypted, -zlib.MAX_WBITS)”,结果出现错误“解压缩数据时出现错误 -3:存储的块长度无效”
  • @Maria stackoverflow.com/questions/3122145/… 这些例子中的任何一个有用吗?我怀疑上面没有给出您的无效存储块长度错误。您能否提供您正在尝试做什么的示例?
  • 不,他们也没有工作!我不确定如何给出更多示例,这就是我们与解压缩相关的所有代码。
  • 谢谢!一旦我们将 java 代码更改为您建议的那样,我们就可以正常工作了,但是用于 android 的 java 没有 getEncoder() 方法,所以我们使用:int length = bytes。长度;放气机放气机=新放气机();放气机.setInput(字节);放气机.finish();字节[]压缩字节=新字节[长度]; deflate.deflate(compressedBytes);放气机.end();返回 Base64.encodeToString(compressedBytes, Base64.DEFAULT);而在python方面,我还没有python 3,所以我们使用了:deflate_bytes=base64.decodestring(base64_binary)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多