使用 StringZipper 压缩解压字符串

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 StringZipper 压缩解压字符串相关的知识,希望对你有一定的参考价值。

数据压缩是一个软件开发中的常见需求:很多时候需要先将较大的数据进行压缩然后再通过网络等进行传输。

在 .NET 中,有多个压缩算法供我们选择:Deflate、GZip 和 Br 。这些压缩算法都是基于流(Stream)的,在对字符串压缩前需要先将其转换成字节数组。

还有一个比较常见的压缩算法是:lz-string 。其官方文档在这里:

https://pieroxy.net/blog/pages/lz-string/index.html

压缩后的数据一般是流或者字节数组,在压缩字符串的场景下,期望的压缩结果大概率也是字符串。常见的字节数组编码方式有以下几种:

  • Base16

  • Base62

  • Base64

  • Ascii85

不同的压缩算法对应了不同的解压缩算法。同样的,不同的编码算法也对应了不同的解码算法。为了降低使用难度,可以在压缩结果中将使用的压缩算法和编码算法嵌入,这样就可以使用一个解压缩方法去解压任意支持的数据。

LuYao.Common

基于上述考虑,笔者编写了一个名为 StringZipper 的静态类用于辅助进行字符串的压缩和解压缩。该类属于 LuYao.Common ,可以在 NuGet 下载:

https://www.nuget.org/packages/LuYao.Common/

StringZipper 的成员

public static class StringZipper

    public interface ICompressor
    
        string Identifier  get; 


        byte[] Compress(string value);


        string Decompress(byte[] data);
    


    public interface IEncoder
    
        string Identifier  get; 


        string Encode(byte[] data);


        byte[] Decode(string value);
    


    public static IEncoder Base16  get; 


    public static IEncoder Base62  get; 


    public static IEncoder Base64  get; 


    public static IEncoder Ascii85  get; 


    public static ICompressor LzString  get; 


    public static ICompressor Deflate  get; 


    public static ICompressor GZip  get; 


    public static ICompressor Br  get; 


    private static void Register(string identifier, object component);


    public static void Register(ICompressor compresser);


    public static void Register(IEncoder encoder);


    public static bool TryGetComponent<T>(string id, out T component);


    public static string Zip(string str, ICompressor compressor, IEncoder encoder);


    public static string Zip(string str);


    public static string Unzip(string str);

使用 StringZipper 压缩字符串

最简单的使用方式就是直接调用 StringZipper 的 Zip 方法,默认情况下会使用 Deflate 压缩算法和 Ascii85 编码:

using LuYao;
var input = "man is distinguished, not only by his reason, but also by this singular passion from other animals; in whom the appetite of food, and other pleasures of sense, by predominance, take away the care of knowing causes; which is a lust of the mind, that by a perseverance of delight in the continual and indefatigable generation of knowledge, exceedeth the short vehemence of any carnal pleasure.";
var output = StringZipper.Zip(input);
Console.WriteLine(output);


var bytesFrom = Encoding.UTF8.GetByteCount(input);
var bytesTo = Encoding.UTF8.GetByteCount(output);


Console.WriteLine("0 => 1 2:0.##%",bytesFrom,bytesTo,1d*bytesTo/bytesFrom);

输出:

data:text/x-deflate;ascii85,<~23?4J`%VHa>G6S<CZ)39YnDE7!KY'd9D=2tfhW"J,^cgm0hTEta?GJmU_ekKWRQilMfOb<fMl1a$n&3T;ti;VBr]sfYusqtXm8:<)4amP&^.pgK[(QXW5PgSMh?,H9f94YdUQrJ@Rc-tTg9*LGZ!ctH5'dj6Z@JZjlBPEZuWoYDp^A@`-W=Fo#t[io.[%&/<8EOoq4^IBD)XDC?UB_qF&Z#KNe*9ZggakM-h-*mulYK`a3gp.VOTjcf`PKIRVtc+T>Ca_=NYjXPN,nMuui]b;FW>@)!NXquZ~>
391 => 320 81.84%

如果需要使用其他的压缩算法或编码方式,Zip 方法有一个需要三个参数的重载,将对应的静态属性传入即可。如果需要使用 Br 压缩和 Base64 编码,则可以使用以下代码:

var output = StringZipper.Zip(input, StringZipper.Br,StringZipper.Base62);

使用 StringZipper 解压字符串

与压缩时可以指定压缩和编码方式相比,解压缩只有一个方法: Unzip 。该方法会自动判断传入的字符串是否被压缩以及压缩时使用的参数:

using LuYao;
var input = "data:text/x-deflate;ascii85,<~23?4J`%VHa>G6S<CZ)39YnDE7!KY'd9D=2tfhW\\"J,^cgm0hTEta?GJmU_ekKWRQilMfOb<fMl1a$n&3T;ti;VBr]sfYusqtXm8:<)4amP&^.pgK[(QXW5PgSMh?,H9f94YdUQrJ@Rc-tTg9*LGZ!ctH5'dj6Z@JZjlBPEZuWoYDp^A@`-W=Fo#t[io.[%&/<8EOoq4^IBD)XDC?UB_qF&Z#KNe*9ZggakM-h-*mulYK`a3gp.VOTjcf`PKIRVtc+T>Ca_=NYjXPN,nMuui]b;FW>@)!NXquZ~>";
var output = StringZipper.Unzip(input);
Console.WriteLine(output);

输出:

man is distinguished, not only by his reason, but also by this singular passion from other animals; in whom the appetite of food, and other pleasures of sense, by predominance, take away the care of knowing causes; which is a lust of the mind, that by a perseverance of delight in the continual and indefatigable generation of knowledge, exceedeth the short vehemence of any carnal pleasure.

路遥工具箱中的功能集成

路遥工具箱已经内置了【文本压缩】功能,在【文字处理】菜单下。其采用的压缩、解压算法与本文所采用的相同。这就代表着可以在开发或者调试时很容易对已压缩的数据进行解压,提高软件开发的效率。

以上是关于使用 StringZipper 压缩解压字符串的主要内容,如果未能解决你的问题,请参考以下文章

GZIP压缩和解压

linux解压带密码的zip的命令是啥

在java中将字符串转换为压缩十进制

Java利用Gzip对字符串进行压缩与解压

C++程序编写压缩器/解压器(长度-游程编码的压缩/解压+霍夫曼编码压缩/解压 (霍夫曼树))

PAT 1078. 字符串压缩与解压