dongyun7571 2019-06-20 01:46
浏览 164
已采纳

Swift和Go之间的Zlib压缩

My Swift application communicates to a server written in Go. I'd like the data transferred to be compressed using Zlib, but it appears that the compression results are different from Swift and Go.

Here is the Go version:

sourceString := "A-t-elle besoin d'autres preuves ? Acceptez-la pour le plaisir. J'ai tant fait que de la cueillir, Et c'est presque une fleur-des-veuves."

// Compression
var b bytes.Buffer
writer := zlib.NewWriter(&b)
writer.Write([]byte(sourceString))
writer.Close()

// Base 64
b64 := base64.StdEncoding.EncodeToString(b.Bytes())

fmt.Println(b64)

It gives the following (Go Playground):

eJwczb2tg0AQReFWbkbylhaeCJy4i/FykUYaLev5IXD1Fs6Pzre1bDQjXoxTB/ZFKp2B6ayLgX9svXMmP80E8yyHEdNEQ33FcxFFykgcool3ETthgl5UM/U/PBJ9YeS9jDuoQRzG8rYz2vVz1m8AAAD//++yMFQ=

Now using the following Swift code (based on this article):

let sourceString = "A-t-elle besoin d'autres preuves ? Acceptez-la pour le plaisir. J'ai tant fait que de la cueillir, Et c'est presque une fleur-des-veuves."

var sourceBuffer = Array(sourceString.utf8)

let destinationBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: sourceString.count)

let algorithm = COMPRESSION_ZLIB

let compressedSize = compression_encode_buffer(destinationBuffer, sourceString.count, &sourceBuffer, sourceString.count, nil, algorithm)

if compressedSize == 0 {
    fatalError("Encoding failed.")
}

// EDIT after @Steffen Ullrich answer
// let encodedString = String(cString: destinationBuffer)
// let encodedStringb64 = Data(encodedString.utf8).base64EncodedString()

let encodedData = NSData(bytesNoCopy: destinationBuffer, length: compressedSize)
let encodedStringb64 = encodedData.base64EncodedString()

print(encodedStringb64)

We get:

H̶e̶+̶/̶v̶T̶E̶O̶7̶7̶+̶9̶M̶A̶x̶D̶0̶a̶t̶w̶7̶7̶+̶9̶U̶u̶+̶/̶v̶Q̶p̶F̶7̶7̶+̶9̶L̶O̶+̶/̶v̶e̶+̶/̶v̶e̶+̶/̶v̶T̶D̶v̶v̶7̶0̶=̶ Hc0xDsMwDEPRq3DzUucKRYYsvYXqMIAAwXFtKUNPX6cTlwf+NXumGfHmOLViTxLeOdA645r7xFoKm/ObTdDO6Ji6mejQvuCVROFSHYeo4xPETkxZgmqm/YHNURKH35fjBlGJwxg97xz5+neWHw==

As you can see it is very different, what am i doing wrong here?

  • 写回答

1条回答 默认 最新

  • duanph1978 2019-06-20 05:49
    关注

    I'm not familiar with Swift but the Go code returns a zlib (RFC 1950) compressed string while according to the documentation from Apple the Swift code should at most return a deflate compressed string (RFC 1951), i.e. like the zlib compressed but without the 2 byte zlib header.

    With that knowledge the string returned from the Go code can be properly decompressed while the string returned from Swift can not. The difference in size is also obvious which lets me assume that something was cut off. It looks like you treat the compressed data destinationBuffer as a cString, which means that any \0-byte inside the string will be treated as the end of the string. It is likely that such \0 byte exists as the result of compression and that the string got cut off there, i.e. that your output shows only part of the real destinationBuffer. (EDIT: the last part does not apply anymore since the OP changed the question with a proper result).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 matlab有关常微分方程的问题求解决
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法