80756


Python3.7で以下のコードを試したところ、出力結果は789c4b4c4c4c040003ce0185でした。

[code]

    import zlib
    
    message = "aaaa"
    
    #文字列をbytes型に変換
    testData = message.encode("utf-8")
    #zlibで圧縮
    compressedData = zlib.compress(testData)
    #16進数文字列に変換
    hexString = compressedData.hex()
    print(hexString)
    
[/code]

Swift5で以下のコードを試したところ、出力結果は4B4C4C4C0400でした。

[code]

    import Foundation
    
    let testString = "aaaa"
    //文字列をdata型(byte型)に変換
    if let testData = testString.data(using: .utf8)
    {
        //zlibで圧縮
        let compressedData = try (testData as NSData).compressed(using: .zlib)
        
        // 各バイトを16進数の文字列に変換。
        let stringArray = compressedData.map{String(format: "%02X", $0)}
        // 16進数を結合する。
        let hexString = stringArray.joined()
        
        print(hexString)
    }
    
[/code]

Python側ではヘッダーとチェックサムがついているのに対してSwift側ではヘッダーとチェックサムが抜けているようです。

Swiftで生成した、ヘッダーとチェックサムが抜けているデータをPython側で受け取る(decompressとdecodeで逆変換する)には、どうしたら良いでしょうか？
または、Swift側でヘッダーとチェックサムを付与させる方法があったりするのでしょうか。


CC BY-SA 4.0
2021-08-12T18:44:06.093
80755
2021-08-12T20:51:06.350
2021-08-12T18:55:20.043
36446
36446
question
python swift
PythonとSwiftでZlibの圧縮結果が違うものになる


以下は Python側での処理です

  * 2バイトのヘッダーと4バイトのチェックサムを取り除く

[code]

    zlib.compress(mesg.encode())[2:-4]
    
[/code]

  * ヘッダーとチェックサム無しのデータを取り扱う

[code]

    zlib.decompress(data, -15).decode()
    
[/code]

参考: <https://stackoverflow.com/questions/1089662/python-inflate-and-deflate-
implementations>


CC BY-SA 4.0
2021-08-12T19:23:39.873
80756
2021-08-12T19:23:39.873
43025
80755
answer


Python側で対応する方法が回答としてついているので、こちらは不要かもしれませんが一応Swift側でも対応できそうと言うことで。

参考記事はこちら。  
[Compress and decompress zlib (RFC 1950) using DEFLATE (RFC 1951)
functions](https://stackoverflow.com/a/59000830/6541007)

[code]

    import Foundation
    import zlib
    
    let testString = "aaaa"
    //文字列をdata型(byte型)に変換
    if let testData = testString.data(using: .utf8)
    {
        //zlibで圧縮
        let compressedData = try (testData as NSData).compressed(using: .zlib)
        
        //チェックサム(Adler-32)を計算
        let adler = testData.withUnsafeBytes {bufPtr in
            adler32(
                1,
                bufPtr.baseAddress!.assumingMemoryBound(to: Bytef.self),
                uInt(bufPtr.count))
        }
        //print(String(format: "%08X", adler))
    
        //ヘッダとチェックサムを付加したデータを作成
        let zlibData = Data([0x78, 0x9C]) + (compressedData as Data)
            + Data([UInt8(adler >> 24),
                    UInt8((adler >> 16) & 0xFF),
                    UInt8((adler >> 8) & 0xFF),
                    UInt8(adler & 0xFF)])
        // 各バイトを16進数の文字列に変換。
        let stringArray = zlibData.map {String(format: "%02X", $0)}
        // 16進数を結合する。
        let hexString = stringArray.joined()
        
        print(hexString)
    }
    
[/code]


CC BY-SA 4.0
2021-08-12T20:51:06.350
80757
2021-08-12T20:51:06.350
13972
80755
answer