diff --git a/Sources/InfomaniakCore/Extensions/Data+Compression.swift b/Sources/InfomaniakCore/Extensions/Data+Compression.swift
new file mode 100644
index 0000000..002c912
--- /dev/null
+++ b/Sources/InfomaniakCore/Extensions/Data+Compression.swift
@@ -0,0 +1,50 @@
+/*
+ Infomaniak Core - iOS
+ Copyright (C) 2023 Infomaniak Network SA
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+import Foundation
+
+/// LZFSE Wrapper
+@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
+public extension Data {
+ /// Compressed data using a zstd like algorithm: lzfse
+ func compressed() -> Self? {
+ guard let data = try? (self as NSData).compressed(using: .lzfse) as Data else {
+ return nil
+ }
+ return data
+ }
+
+ /// Decompressed data from a lzfse buffer
+ func decompressed() -> Self? {
+ guard let data = try? (self as NSData).decompressed(using: .lzfse) as Data else {
+ return nil
+ }
+ return data
+ }
+
+ // MARK: - String helpers
+
+ /// Decompressed string from a lzfse buffer
+ func decompressedString() -> String? {
+ guard let decompressedData = decompressed() else {
+ return nil
+ }
+ let string = String(decoding: decompressedData, as: UTF8.self)
+ return string
+ }
+}
diff --git a/Sources/InfomaniakCore/Extensions/String+Compression.swift b/Sources/InfomaniakCore/Extensions/String+Compression.swift
new file mode 100644
index 0000000..21d59cb
--- /dev/null
+++ b/Sources/InfomaniakCore/Extensions/String+Compression.swift
@@ -0,0 +1,35 @@
+/*
+ Infomaniak Core - iOS
+ Copyright (C) 2023 Infomaniak Network SA
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+import Foundation
+
+/// LZFSE Wrapper
+@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
+public extension String {
+ func compressed() -> Data? {
+ guard let data = data(using: .utf8),
+ let compressed = data.compressed() else {
+ return nil
+ }
+ return compressed
+ }
+
+ static func decompressed(from data: Data) -> Self? {
+ data.decompressedString()
+ }
+}
diff --git a/Tests/InfomaniakCoreTests/UTCompression.swift b/Tests/InfomaniakCoreTests/UTCompression.swift
new file mode 100644
index 0000000..5d58a15
--- /dev/null
+++ b/Tests/InfomaniakCoreTests/UTCompression.swift
@@ -0,0 +1,54 @@
+/*
+ Infomaniak Core - iOS
+ Copyright (C) 2023 Infomaniak Network SA
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+import InfomaniakCore
+import XCTest
+
+@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
+final class UTCompression: XCTestCase {
+ func testCompression() {
+ // GIVEN
+ let lowEntropy = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
+ let lowEntropyData = lowEntropy.data(using: .utf8)!
+
+ // WHEN
+ guard let highEntropy = lowEntropy.compressed() else {
+ XCTFail("Unexpected")
+ return
+ }
+
+ // THEN
+ XCTAssertLessThan(highEntropy.count, lowEntropyData.count, "Compressed message should be smaller")
+ }
+
+ func testCompressionDecompression() {
+ // GIVEN
+ let lowEntropy = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
+
+ // WHEN
+ guard let highEntropy = lowEntropy.compressed() else {
+ XCTFail("Unexpected")
+ return
+ }
+
+ let decompressedString = highEntropy.decompressedString()
+
+ // THEN
+ XCTAssertEqual(lowEntropy, decompressedString)
+ }
+}