Python上的zlib.compress和Java(Android)上的Deflater.deflate是否兼容?
我正在将一个Python应用程序移植到Android上,在某个时候,这个应用程序必须与Web服务通信,向它发送压缩数据 为此,它使用下一种方法:Python上的zlib.compress和Java(Android)上的Deflater.deflate是否兼容?,java,python,android,zlib,deflate,Java,Python,Android,Zlib,Deflate,我正在将一个Python应用程序移植到Android上,在某个时候,这个应用程序必须与Web服务通信,向它发送压缩数据 为此,它使用下一种方法: def stuff(self, data): "Convert into UTF-8 and compress." return zlib.compress(simplejson.dumps(data)) 我正在使用下一种方法尝试在Android中模拟这种行为: private String compressString(String
def stuff(self, data):
"Convert into UTF-8 and compress."
return zlib.compress(simplejson.dumps(data))
我正在使用下一种方法尝试在Android中模拟这种行为:
private String compressString(String stringToCompress)
{
Log.i(TAG, "Compressing String " + stringToCompress);
byte[] input = stringToCompress.getBytes();
// Create the compressor with highest level of compression
Deflater compressor = new Deflater();
//compressor.setLevel(Deflater.BEST_COMPRESSION);
// Give the compressor the data to compress
compressor.setInput(input);
compressor.finish();
// Create an expandable byte array to hold the compressed data.
// You cannot use an array that's the same size as the orginal because
// there is no guarantee that the compressed data will be smaller than
// the uncompressed data.
ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);
// Compress the data
byte[] buf = new byte[1024];
while (!compressor.finished())
{
int count = compressor.deflate(buf);
bos.write(buf, 0, count);
}
try {
bos.close();
} catch (IOException e)
{
}
// Get the compressed data
byte[] compressedData = bos.toByteArray();
Log.i(TAG, "Finished to compress string " + stringToCompress);
return new String(compressedData);
}
但是来自服务器的HTTP响应是不正确的,我想这是因为Java中的压缩结果与Python中的结果不同
我用zlib.compress和deflate运行了一个压缩“a”的小测试
Python,zlib.compress()->x%9CSJT%02%00%01M%00%A6
Android,Deflater.deflate->H%EF%BF%BDK%04%00%00b%00b
我应该如何在Android中压缩数据以获得与Python中zlib.compress()相同的值
非常感谢您的帮助、指导或指点 Does
byte[]input=stringToCompress.getBytes(“utf-8”)代码>帮助?如果平台的默认编码不是UTF-8,这将强制编码字符串->字节使用UTF-8。同样,代码的最后一行也是如此,在这里您创建了一个新字符串
——您可能希望明确指定UTF-8作为解码字符集。压缩和放气是不同的压缩算法,因此答案是它们不兼容。作为差异的一个示例,这里是通过Tcl使用两种算法压缩的“a”:
% binary encode hex [zlib compress a]
789c4b040000620062
% binary encode hex [zlib deflate a]
4b0400
您的python代码确实在进行压缩。android代码正在进行deflate,但是您也会在android版本(\xef\xbf\xbf)前面添加UTF-8字节顺序标记
可以使用python发出deflate数据:
def deflate(data):
zobj = zlib.compressobj(6,zlib.DEFLATED,-zlib.MAX_WBITS,zlib.DEF_MEM_LEVEL,0)
zdata = zobj.compress(data)
zdata += zobj.flush()
return zdata
虽然它们不是完全相同的算法,但它们似乎完全兼容(这意味着,如果使用Deflater.deflate压缩字符串,则可以使用zlib正确解压缩)
导致我的问题的原因是POST中的所有表单变量都需要进行%转义,而Android应用程序没有这样做。在发送数据之前将数据编码到Base64,并在使用zlib解压之前修改服务器以使用Base64对其进行解码,解决了此问题。感谢您的建议!我将尝试一下,并告诉你它是如何进行的,尽管我认为默认编码已经是UTF-8了,但还是要小心。我测试了这个建议,但没有改变结果。无论如何谢谢你!这就是我所怀疑的,它们实际上是不同的压缩方法。现在,我可以集中精力寻找一种方法来生成与Java中的zlib.compress相同的压缩(我测试了您的Python代码,它确实像Java版本一样压缩数据,但由于我正在将应用程序移植到Android,并且无法修改原来的应用程序,所以我正在寻找另一种方法:在Java上进行压缩)。无论如何,到目前为止,这个答案真的很有帮助!如果可以,我会投票支持你:p行返回新字符串(compressedData)代码>是一个bug。不能那样使用字符串。
>>> deflate("a")
'K\x04\x00'