Сжатие Zlib между Swift и Go - PullRequest
       35

Сжатие Zlib между Swift и Go

0 голосов
/ 20 июня 2019

Приложение My Swift связывается с сервером, написанным на Go.Я бы хотел, чтобы передаваемые данные были сжаты с помощью Zlib, но похоже, что результаты сжатия отличаются от Swift и Go.

Вот версия Go:

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)

Это дает следующее ( Go площадка ):

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

Теперь, используяследующий Swift код ( на основе этой статьи ):

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)

Мы получаем:

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

Как вы можете видеть, что это очень разные, то, что яя здесь не так делаю?

1 Ответ

0 голосов
/ 20 июня 2019

Я не знаком со Swift, но код Go возвращает сжатую строку zlib (RFC 1950), в то время как в соответствии с документацией Apple код Swift должен в большинстве случаев возвращать сжатую строку deflate (RFC 1951), т. Е. Подобно zlib сжатый, но без 2-байтового заголовка zlib.

С этим знанием строка, возвращаемая из кода Go, может быть правильно распакована, в то время как строка, возвращенная из Swift, не может. Разница в размерах также очевидна, что позволяет предположить, что что-то было отрезано. Похоже, вы рассматриваете сжатые данные destinationBuffer как cString, что означает, что любой \0 -байт внутри строки будет считаться концом строки. Вполне вероятно, что такой \0 байт существует в результате сжатия и что строка там обрезана, то есть, что ваш вывод показывает только часть действительного destinationBuffer. (РЕДАКТИРОВАТЬ: последняя часть больше не применяется, так как ОП изменил вопрос с правильным результатом).

...