字符串压缩不适用于较小的字符串

时间:2013-12-04 12:18:44

标签: c# string compression

我试图在c#中压缩字符串“XZJ6RTNN4NNNNNNR8YWWX7ZGWO1XXQT6PSRT5281I0WQZM75K2P3SPH81XN4M3L1WF6Q”。 我正在使用"https://stackoverflow.com/questions/7343465/compression-decompression-string-with-c-sharp?rq=1"链接中标记为已回答的代码。但我得到的压缩字符串大于输入。标记为已回答的代码无效。请告诉我们如何减少此字符串大小。

   public static void CopyTo(Stream src, Stream dest) {
    byte[] bytes = new byte[4096];

    int cnt;

    while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
        dest.Write(bytes, 0, cnt);
    }
}

public static byte[] Zip(string str) 
{
    var bytes = Encoding.UTF8.GetBytes(str);

    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream()) {
        using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
            //msi.CopyTo(gs);
            CopyTo(msi, gs);
        }

        return mso.ToArray();
    }
}

public static string Unzip(byte[] bytes) {
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream()) {
        using (var gs = new GZipStream(msi, CompressionMode.Decompress)) {
            //gs.CopyTo(mso);
            CopyTo(gs, mso);
        }

        return Encoding.UTF8.GetString(mso.ToArray());
    }
}

static void Main(string[] args) {
    byte[] r1 = Zip("StringStringStringStringStringStringStringStringStringStringStringStringStringString");
    string r2 = Unzip(r1);
}

3 个答案:

答案 0 :(得分:1)

是的,具有高熵的短值通常在“压缩”它们时变得更大而不是更小。这是压缩如何工作的简单特征。因此,许多协议包括“被压缩”标志,以允许有效地发送短或高熵有效载荷 - 有时由估计器发送(例如,如果小于100字节则不尝试),或者有时通过尝试压缩,然后发送较小的一个。

答案 1 :(得分:0)

我将使用该主题的其中一条评论:

“没有理由这样做,并且没有理由不这样做。你不会节省大量空间,而且你的数据库渲染不可用。存储空间是你可以买到的最便宜的商品。节省数千美元字符串“100到200个字符”将是微不足道的,小于1兆字节。不要这样做,将字符串保存在未压缩状态。“

答案 2 :(得分:0)

看起来你的字符串实际上可能是一个base-64编码的字节数组。

如果是这种情况,那么你可以通过将其转换回字节数组来“压缩”它:

string original = "XZJ6RTNN4NNNNNNR8YWWX7ZGWO1XXQT6PSRT5281I0WQZM75K2P3SPH81XN4M3L1WF6Q";
Console.WriteLine("Original #characters = " + original.Length + " characters, or byte count = " + 2*original.Length);
byte[] compressed = Convert.FromBase64String(original);
Console.WriteLine("Compressed length = " + compressed.Length);
string decompressed = Convert.ToBase64String(compressed);

if (decompressed == original)
    Console.WriteLine("Decompressed OK");
else
    Console.WriteLine("Failed to decompress!");

此代码的输出为:

Original #characters = 68 characters, or byte count = 136
Compressed length = 51
Decompressed OK

所以我们从68个字符(或136个字节,如果字符是UTF16)减少到51个字节。

请注意,这根本不是压缩数据。它只是将base-64 ASCII表示转换回原始格式,假设它真的是base-64 ASCII。

如果不是,那么显然你不能将它转换回字节数组。

我发布此信息只是为了提醒您可能是您正在处理的基本64位ASCII编码数据这一事实,您应该检查是否是这种情况。