I thought I would share this answer for anyone interested in reproducing this on PowerShell, the code is mostly inspired from Timwi's helpful answer, however unfortunately as of now there is no implementation for the using statement like on C# for PowerShell, hence the need to manually dispose the streams before output.
Functions below requires PowerShell 5.0+.
- Compression from string to Base64 GZip compressed string:
using namespace System
using namespace System.Text
using namespace System.IO
using namespace System.IO.Compression
function Compress-GzipString {
[cmdletbinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string]$String,
[string]$Encoding = 'UTF8'
)
try {
$outStream = [MemoryStream]::new()
$gzip = [GZipStream]::new(
$outStream,
[CompressionMode]::Compress,
[CompressionLevel]::Optimal
)
$inStream = [MemoryStream]::new(
[Encoding]::$Encoding.GetBytes($string)
)
$inStream.CopyTo($gzip)
}
catch {
$PSCmdlet.WriteError($_)
}
finally {
($gzip, $outStream, $inStream).ForEach('Dispose')
}
try {
[Convert]::ToBase64String($outStream.ToArray())
}
catch {
$PSCmdlet.WriteError($_)
}
}
- Expansion from Base64 GZip compressed string to string:
function Expand-GzipString {
[cmdletbinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string]$String,
[string]$Encoding = 'UTF8'
)
try {
$bytes = [Convert]::FromBase64String($String)
$outStream = [MemoryStream]::new()
$inStream = [MemoryStream]::new($bytes)
$gzip = [GZipStream]::new(
$inStream,
[CompressionMode]::Decompress
)
$gzip.CopyTo($outStream)
[Encoding]::$Encoding.GetString($outStream.ToArray())
}
catch {
$PSCmdlet.WriteError($_)
}
finally {
($gzip, $outStream, $inStream).ForEach('Dispose')
}
}
And for the little Length comparison, querying the Loripsum API:
$loremIp = Invoke-RestMethod loripsum.net/api/10/long
$compressedLoremIp = Compress-GzipString $loremIp
$loremIp, $compressedLoremIp | Select-Object Length
Length
------
8353
4940
(Expand-GzipString $compressedLoremIp) -eq $loremIp # => Should be True