6

Python アプリケーションを Android に移植していますが、ある時点で、このアプリケーションは Web サービスと通信し、圧縮データを送信する必要があります。

そのために、次の方法を使用します。

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() の同じ値を取得するにはどうすればよいですか?

ヘルプ、ガイダンス、またはポインタは大歓迎です!

4

3 に答える 3

7

compressとdeflateは異なる圧縮アルゴリズムであるため、答えは互換性がないということです。ここでの違いの例として、Tclを介して2つのアルゴリズムを使用して圧縮された「a」があります。

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

あなたのPythonコードは確かに圧縮を行っています。また、Androidコードはデフレートを実行していますが、Androidバージョン(\ xef \ xbf \ xbf)の前にUTF-8バイト順マークが追加されています。

Pythonを使用してデフレートデータを出力できます。

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
>>> deflate("a")
'K\x04\x00'
于 2010-03-11T16:28:29.893 に答える
2

それらはまったく同じアルゴリズムではありませんが、完全に互換性があるようです (つまり、たとえば、Deflater.deflate を使用して文字列を圧縮すると、zlib を使用して正しく圧縮解除できます)。

私の問題の原因は、POST 内のすべてのフォーム変数をパーセントでエスケープする必要があり、Android アプリケーションがそれを行っていなかったことです。データを送信する前にBase64にエンコードし、zlibを使用して圧縮解除する前にBase64を使用してデコードするようにサーバーを変更すると、問題が解決しました。

于 2011-11-05T17:40:58.367 に答える
0

byte[] input = stringToCompress.getBytes("utf-8");役に立ちますか?プラットフォームのデフォルトのエンコーディングが UTF-8 でない場合、文字列 -> バイトのエンコーディングに UTF-8 を使用するように強制します。また、コードを作成する最後の行についても同じnew Stringことが言えます。デコード文字セットとして UTF-8 を明示的に指定することもできます。

于 2010-03-11T13:09:18.787 に答える