【问题标题】:Gzip compress/uncompress a long char arrayGzip 压缩/解压缩长字符数组
【发布时间】:2015-02-06 10:46:03
【问题描述】:

我需要压缩一个大字节数组,我已经在应用程序中使用 Crypto++ 库,所以在同一个库中包含压缩/解压缩部分会很棒。

这个小测试按预期工作:

///
string test = "bleachbleachtestingbiatchbleach123123bleachbleachtestingb.....more";
string compress(string input)
{
    string result ("");
    CryptoPP::StringSource(input, true, new CryptoPP::Gzip(new CryptoPP::StringSink(result), 1));
    return result;
}

string decompress(string _input)
{
    string _result ("");
    CryptoPP::StringSource(_input, true, new CryptoPP::Gunzip(new CryptoPP::StringSink(_result), 1));
    return _result;
}

void main()
{
    string compressed = compress(test);
    string decompressed = decompress(compressed);
    cout << "orginal size :" << test.length() << endl;
    cout << "compressed size :" << compressed.length() << endl;
    cout << "decompressed size :" << decompressed.length() << endl;
    system("PAUSE");
}

我需要压缩这样的东西:

unsigned char long_array[194506]
{
  0x00,0x00,0x02,0x00,0x00,0x04,0x00,0x00,0x00,
  0x01,0x00,0x02,0x00,0x00,0x04,0x02,0x00,0x04,
  0x04,0x00,0x02,0x00,0x01,0x04,0x02,0x00,0x04,
  0x01,0x00,0x02,0x02,0x00,0x04,0x02,0x00,0x00,
  0x03,0x00,0x02,0x00,0x00,0x04,0x01,0x00,0x04,
  ....
};

我尝试将 long_array 用作 const char * 并用作 byte 然后将其提供给 compress 函数,它似乎已被压缩,但解压缩后的大小为 4,并且显然不完整。也许它太长了。 我如何重写那些压缩/解压缩函数以使用该字节数组? 谢谢你们。 :)

【问题讨论】:

  • 也许compress() 会在它看到的第一个 NULL 字节处停止,因为它不需要参数来明确指定要压缩的数据的长度。如果是这种情况,您可能需要使用不同的函数来压缩任意二进制数据。不过,我对 Crypto++ 并不太熟悉……
  • 是的,它在第一个空字节后停止。我无法找到文档/剪辑以使用字节数组。
  • Crypto++ wiki 现在有一个 Gzip 页面,包括一个允许您读取和写入修改文件时间、原始文件名和 cmets 的补丁。请参阅Gzip wiki 页面。

标签: c++ arrays visual-c++ gzip crypto++


【解决方案1】:

我尝试将数组用作 const char * 并用作 byte 然后将其提供给 compress 函数,它似乎已被压缩但解压缩后的大小为 4,并且它显然不完整。

使用采用pointer and a length 的备用StringSource 构造函数。它将不受嵌入式NULL's 的影响。

CryptoPP::StringSource ss(long_array, sizeof(long_array), true,
    new CryptoPP::Gzip(
        new CryptoPP::StringSink(result), 1)
));

或者,您可以使用:

Gzip zipper(new StringSink(result), 1);
zipper.Put(long_array, sizeof(long_array));
zipper.MessageEnd();

Crypto++ 在 5.6 中添加了 ArraySource。你也可以使用它(但它实际上是 typedef 用于 StringSource):

CryptoPP::ArraySource as(long_array, sizeof(long_array), true,
    new CryptoPP::Gzip(
        new CryptoPP::StringSink(result), 1)
));

用作Gzip 参数的1 是一个放气级别。 1 是最低压缩率之一。您可以考虑使用9Gzip::MAX_DEFLATE_LEVEL(即9)。默认 log2 窗口大小是最大大小,因此无需转动任何旋钮。

Gzip zipper(new StringSink(result), Gzip::MAX_DEFLATE_LEVEL);

您还应该为您的声明命名。我看到 GCC 在使用匿名声明时会生成错误的代码。

最后,使用 long_array(或类似名称),因为 array 是 C++ 11 中的关键字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2012-02-12
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多