2010-03-11 3 views
6

나는 Python 애플리케이션을 Android로 포팅하고 있으며,이 애플리케이션은 웹 서비스와 통신하여 압축 된 데이터를 전송해야한다. 나는 안드로이드에서이 동작을 모방하려고 다음 방법을 사용하고Python의 zlib.compress와 Java (Android)의 Deflater.deflate는 호환됩니까?

def stuff(self, data): 
    "Convert into UTF-8 and compress." 
    return zlib.compress(simplejson.dumps(data)) 

:

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 응답은 다음 방법을 사용하여 그렇게하기 위해

서버가 올바르지 않습니다. 자바 압축 결과가 파이썬과 동일하지 않기 때문에 서버가 올바르지 않습니다.

나는 zlib.compress와 deflate를 사용하여 "a"를 약간 압축하여 테스트했습니다.

파이썬 zlib.compress() -> X % 9CSJT % 02퍼센트 00% 01M %의 00퍼센트의 A6

안드로이드 Deflater.deflate -> H의 %의 EF 체지방률의 %의 BDK % 04% 00% 송신 00b % 00b

Python에서 zlib.compress()와 동일한 값을 얻으려면 Android에서 데이터를 어떻게 압축해야합니까?

도움, 안내 또는 포인터가 대단히 감사합니다!

+0

줄'return new String (compressedData);는 버그입니다. 그런 식으로 문자열을 사용할 수 없습니다. –

답변

2

정확히 동일한 알고리즘은 아니지만 완전히 호환 가능합니다 (예 : Deflater.deflate를 사용하여 문자열을 압축하면 zlib을 사용하여 올바르게 압축 할 수 있음).

내 문제의 원인은 POST의 모든 양식 변수를 이스케이프 처리해야하고 Android 애플리케이션이 그렇게하지 않았기 때문입니다. 데이터를 보내기 전에 Base64로 인코딩하고 zlib를 사용하여 Base64로 압축을 풀기 전에 Base64를 사용하여 디코딩하도록 서버를 수정하면 문제가 해결됩니다.

0

byte[] input = stringToCompress.getBytes("utf-8");이 도움이 되나요? 플랫폼의 기본 인코딩이 UTF-8이 아닌 경우 인코딩 문자열 -> 바이트가 UTF-8을 사용하도록합니다. 또한 new String을 만드는 코드의 마지막 줄에 대해서도 마찬가지입니다. UTF-8을 디코딩 Charset으로 명시 적으로 지정하고자 할 수 있습니다.

+0

제안 해 주셔서 감사합니다. 나는 그것을 시험해보고 그것이 어떻게되는지에 대해 이야기 할 것이지만 기본 인코딩은 이미 UTF-8이 항상 신중해야한다고 생각하기는하지만. –

+0

나는 그 제안을 시험하지만 결과를 바꾸지 않았다. 어쨌든 고마워! –

7

압축과 압축은 서로 다른 압축 알고리즘이므로 서로 호환되지 않습니다.

% binary encode hex [zlib compress a] 
789c4b040000620062 
% binary encode hex [zlib deflate a] 
4b0400

파이썬 코드가 실제로 수행되고 압축 : 차이의 예로서 여기에서 'A'티클 통해 두 알고리즘을 사용하여 압축된다.

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 
: 그리고 안드로이드 코드 그러나 당신은 또한

당신은 파이썬을 사용하여 데이터를 수축 방출 할 수있다 (XBF \ XBF XEF \ \) 안드로이드 버전으로 앞에 붙은 UTF-8 바이트 순서 표시를 얻고, 폐하고있다

+0

그것이 제가 실제로 의심했던 것입니다. 사실 그들은 다른 압축 방법이었습니다. 이제 zlib의 동일한 압축을 생성하는 방법을 찾는 데 집중할 수 있습니다.Java에서 압축 (파이썬 코드를 테스트 한 결과 Java 버전과 같은 데이터를 실제로 압축했지만 Android로 이식하고 원래 파일을 수정할 수 없기 때문에 다른 방법을 찾고있었습니다. Java에서 압축하기). 어쨌든, 지금까지 도움이되는 답변입니다! 내가 할 수 있으면 나는 당신을 투표 할 것입니다 : P –

+0

+1 (이제 할 수 있습니다) –