C#使用Brotli压缩/解压文本

Brotli

Brotli 是一种通用的无损压缩算法。它结合使用 LZ77 算法的一个现代变体(Lempel-Ziv 编码)、霍夫曼编码和二阶上下文建模来压缩数据,提供了与当前最佳通用压缩方法相媲美的压缩比。

Brotli 提供比 gzip 更好的压缩率,压缩速率也与 deflate 相当。但 brotli 压缩速度比 gzip 慢,因此 gzip 可能更适合于压缩不可缓存的内容。

System.IO.Compression.BrotliEncoder

微软出品,提供方法和静态方法,以便使用 Brotli 数据格式规范以无流、非分配和高性能的方式对数据进行编码和解码。

Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void Test1(string str)
{
System.IO.Compression.BrotliEncoder encoder = new System.IO.Compression.BrotliEncoder();
var bytes = Encoding.Default.GetBytes(str);
byte[] array = new byte[bytes.Length];
var res = encoder.Compress(bytes, array, out int consumed, out int written, true);
string EncodeB64Str = Convert.ToBase64String(array, 0, written);
Console.WriteLine(EncodeB64Str);

byte[] output = new byte[consumed];
System.IO.Compression.BrotliDecoder decoder = new System.IO.Compression.BrotliDecoder();
var res1 = decoder.Decompress(array, output, out int deconsumed, out int dewritten);
var result = Encoding.Default.GetString(output,0,dewritten);
Console.WriteLine(result);
}

Demo2(简单封装一下):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static string BrEncoder(string str)
{
System.IO.Compression.BrotliEncoder encoder = new System.IO.Compression.BrotliEncoder();
var bytes = Encoding.Default.GetBytes(str);
Span<byte> output = new Span<byte>(new byte[bytes.Length * 2]);
var res = encoder.Compress(bytes, output, out int consumed, out int written, true);
byte[] resultArray = new byte[written];
Array.Copy(output.ToArray(), resultArray, written);
return Convert.ToBase64String(resultArray);
}
public static string BrDecoder(string EncodeB64Str)
{
var bytes = Convert.FromBase64String(EncodeB64Str);
Span<byte> output = new Span<byte>(new byte[4096]);
System.IO.Compression.BrotliDecoder decoder = new System.IO.Compression.BrotliDecoder();
var res1 = decoder.Decompress(bytes, output, out int deconsumed, out int dewritten);
var result = Encoding.Default.GetString(output);
return result;
}

public static void Test1(string str)
{
var res1 = BrEncoder(str);
Console.WriteLine(res1);
var res2 = BrDecoder(res1);
Console.WriteLine(res2);
}

Brotli.NET

The .net implement of the brotli algorithm,provide similar interface to Google offical API.

Quality and window control is supported.

Supported and tested on:

  • Dotnet standard 2(.NET Framework [v4.6.1] and .net core [2] above)
  • Windows/Linux/MacOSX
  • .NET Framework v4.5
  • Besides quality controll,the library use the native runtime and its performance should be better than System.IO.Compress.BrotliStream.

Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using Brotli;
public static void Test3(string str)
{
var bytes = Encoding.Default.GetBytes(str);
var output= bytes.CompressToBrotli();
string EncodeB64Str = Convert.ToBase64String(output);
Console.WriteLine(EncodeB64Str);

var bytesNeedDecode = Convert.FromBase64String(EncodeB64Str);
var decompressedData = bytesNeedDecode.DecompressFromBrotli();
var result = Encoding.Default.GetString(decompressedData);
Console.WriteLine(result);
}

EasyCompressor

一个易于使用且经过优化的 .NET 压缩库,它统一了多种压缩算法,包括 LZ4、Snappy、Zstd、LZMA、Brotli、GZip、ZLib 和 Deflate。

Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using EasyCompressor;
public static void Test4(string str)
{
var _compressor = new BrotliCompressor();
var bytes = Encoding.Default.GetBytes(str);
var compressedBytes = _compressor.Compress(bytes);

string EncodeB64Str = Convert.ToBase64String(compressedBytes);
Console.WriteLine(EncodeB64Str);

var bytesNeedDecode = Convert.FromBase64String(EncodeB64Str);
var uncompressedBytes = _compressor.Decompress(bytesNeedDecode);
var result = Encoding.Default.GetString(uncompressedBytes);
Console.WriteLine(result);
}

BrotliSharpLib

BrotliSharpLib 是 Google 提供的 brotli 库/压缩代码的完整 C# 端口。它旨在成为原始 C 代码的大部分 1:1 转换。截至参考实现的 v0.6.0,所有代码都是正确的。

这些项目使用最少的 API 集来确保与各种框架(包括 .NET Standard 和 .NET Core)兼容。它还支持 little-endian 和 big-endian 架构,并针对 x86、x64 和 ARM 处理器进行了优化。
(这个能在Blazor上使用)

Demo:

1
2
3
4
5
6
7
8
9
10
11
12
public static void Test5(string str)
{
byte[] brotliCompressedData = Encoding.Default.GetBytes(str);
byte[] compressedBytes = BrotliSharpLib.Brotli.CompressBuffer(brotliCompressedData, 0, brotliCompressedData.Length /**, customDictionary **/);
string EncodeB64Str = Convert.ToBase64String(compressedBytes);
Console.WriteLine(EncodeB64Str);

var bytesNeedDecode = Convert.FromBase64String(EncodeB64Str);
var uncompressedBytes = BrotliSharpLib.Brotli.DecompressBuffer(bytesNeedDecode,0,bytesNeedDecode.Length);
var result = Encoding.Default.GetString(uncompressedBytes);
Console.WriteLine(result);
}

源码下载