Question

Je suis une application PORTAGE Python pour Android et, à un moment donné, cette application doit communiquer avec un service Web, envoyer des données compressées.

Pour ce faire, il utilise la méthode suivante:

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

J'utilise la méthode suivante pour essayer d'imiter ce comportement dans 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);
}

Mais la réponse HTTP à partir du serveur n'est pas correct et je suppose que c'est parce que le résultat de la compression en Java n'est pas le même que celui en Python.

J'ai couru un petit test de compression « un » à la fois avec zlib.compress et dégonfler.

python, zlib.compress () -> x% 9CSJT% 02% 00% 00% 01M% A6

applications, Deflater.deflate -> H% EF% BF% BDK% 04% 00% 00b 00b%

Comment dois-je compresser les données dans Android pour obtenir la même valeur de zlib.compress () en Python?

Toute aide, d'orientation ou pointeur est grandement apprécié!

Était-ce utile?

La solution 2

Bien qu'ils ne sont pas exactement les mêmes algorithmes, il semble qu'ils sont totalement compatibles (ce qui signifie que si vous compressez, par exemple, une chaîne en utilisant Deflater.deflate vous pouvez correctement décompresser en utilisant zlib).

Ce qui a causé mon problème était que toutes les variables de formulaire dans un POST doivent être pour cent échappé, et l'application Android n'a pas fait cela. Coder les données de base 64 avant de l'envoyer, et en modifiant le serveur pour décoder à l'aide de base64 avant la décompression à l'aide de zlib résolu le problème.

Autres conseils

compresser et dégonfler sont différents algorithmes de compression de sorte que la réponse est qu'ils ne seront pas compatibles. À titre d'exemple de la différence est ici « a » compressé en utilisant les deux algorithmes via Tcl:

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

Votre code python fait en effet compress. Et le code Android est en train de faire dégonfler, mais vous obtenez également la marque de l'ordre des octets UTF-8 préfixera la version Android (\ xef \ XBF \ XBF)

Vous pouvez émettre des données en utilisant dégonflage 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'

Est-ce que byte[] input = stringToCompress.getBytes("utf-8"); aide? Dans le cas où votre encodage par défaut de la plate-forme n'est pas UTF-8, cela forcera l'encodage String -> octets à utiliser UTF-8. En outre, la même chose pour la dernière ligne de votre code où vous créez un new String -. Vous pouvez spécifier explicitement UTF-8 comme le décodage Charset

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top