Convert compress functions from Python to Kotlin
I have functions in Python for compression and decompression of a string (bytearray):
def compress_message(data):
compressor = zlib.compressobj(-1, zlib.DEFLATED, 31, 8, zlib.Z_DEFAULT_STRATEGY)
compressed_data = compressor.compress(data)
compressed_data += compressor.flush()
return compressed_data
def decompress_message(compressed_data):
return zlib.decompress(compressed_data, wbits=31)
I need to convert these functions to kotlin, so I can use them in my mobile app. So far I tried this:
fun String.zlibCompress(): ByteArray {
val input = this.toByteArray(charset("UTF-8"))
val output = ByteArray(input.size * 4)
val compressor = Deflater().apply {
setLevel(-1)
setInput(input)
finish()
}
val compressedDataLength: Int = compressor.deflate(output)
return output.copyOfRange(0, compressedDataLength)
}
However, it gives totally different results for example for string abcdefghijklmnouprstuvwxyz
:
Python: 1f8b080000000000000a4b4c4a4e494d4bcfc8cccacec9cdcb2f2d282a2e292d2bafa8ac0200c197b2d21a000000
Kotlin: 789c4b4c4a4e494d4bcfc8cccacec9cdcb2f2d282a2e292d2bafa8ac020090b30b24
Is there any way, how can I modify the kotlin code, so it gives same result as Python?
Thanks for your replies. <3
The 31
parameter in the Python code is requesting a gzip stream, not a zlib stream. In Kotlin, you are generating a zlib stream. (zlib is described in RFC 1950, gzip in RFC 1952.)
It does not appear that Java's Deflater
(spelled wrong) class has that option. It does have a nowrap
option that gives raw deflate compressed data, around which you can construct your own gzip wrapper, using the RFC to see how.
By the way, the results are not "totally different". You have gzip and zlib wrappers around exactly the same raw deflate compressed data: 4b4c
...0020
.