هل Zlib.compress على Python و Deflater.deflate على Java (Android) متوافق؟
سؤال
أقوم بتنفيذ تطبيق Python على Android، وفي مرحلة ما، يتعين على هذا التطبيق التواصل مع خدمة ويب، وإرسال البيانات المضغوطة.
من أجل القيام بذلك يستخدم الطريقة التالية:
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 من الخادم غير صحيح وأعتقد أنه لأن نتيجة الضغط في جافا ليست هي نفسها واحدة في بيثون.
ركضت قليلا اختبار ضغط "A" مع zlib.compress وانفتح.
بيثون، zlib.compress () -> X٪ 9CSJT٪ 02٪ 00٪ 01M٪ 00٪ A6
Android، deflater.deflate -> H٪ EF٪ BF٪ BDK٪ 04٪ 00٪ 00B٪ 00B
كيف يجب أن أقوم بضغط البيانات في Android للحصول على نفس قيمة zlib.compress () في بيثون؟
أي مساعدة أو إرشادات أو مؤشر موضع تقدير كبير!
المحلول 2
على الرغم من أنها ليست نفس الخوارزميات بالضبط، إلا أنها تبدو متوافقة تماما (مما يعني أنه إذا قمت بضغط، على سبيل المثال، سلسلة باستخدام Deflater.Deflate يمكنك بشكل صحيح إلغاء ضغطه باستخدام ZLIB).
ما تسبب مشكلتي في أن جميع متغيرات النموذج في مرحلة ما تحتاج إلى أن تتجه في المئة، وكان تطبيق أندرويد لا يفعل ذلك. قم بترميز البيانات إلى Base64 قبل إرسالها، وتعديل الخادم لفك تشفيره باستخدام Base64 قبل إلغاء ضغطه باستخدام ZLIB حل المشكلة.
نصائح أخرى
ضغط وانفتحان عبارة عن خوارزميات ضغط مختلفة بحيث تكون الإجابة أنها لن تكون متوافقة. كمثال على الفرق هنا هو مضغوط "باستخدام الخوارزمتين عبر TCL:
% binary encode hex [zlib compress a]
789c4b040000620062
% binary encode hex [zlib deflate a]
4b0400
رمز بيثون الخاص بك هو بالفعل ضغط. وكود Android يقوم بتحريك، ومع ذلك، فإنك تحصل أيضا على علامة طلب البايت UTF-8 Refended إلى إصدار Android ( Xef XBF XBF)
يمكنك تنبعث بيانات صهر باستخدام 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'
هل byte[] input = stringToCompress.getBytes("utf-8");
مساعدة؟ في حالة الترميز الافتراضي للمنصة الخاصة بك ليس UTF-8، سيجبر ذلك على سلسلة الترميز -> بايت لاستخدام UTF-8. أيضا، الشيء نفسه ينطبق على السطر الأخير من التعليمات البرمجية الخاصة بك حيث يمكنك إنشاء new String
- قد ترغب في تحديد OUTF-8 بشكل صريح كمنشط فك التشفير.