录十六

持之以恒

deflate和gzip的区别

deflate是一种使用了LZ77算法与哈夫曼编码(Huffman Coding)实现的无损数据压缩算法。它是一个无专利的,可以自由使用的算法。

gizp是一种以0x1F8B标志开头的数据格式,其内部通常采用DEFLATE算法对数据进行压缩。

下面附上基于zlib库实现的gzip数据压缩和解压缩函数:

//gzip解压缩
std::string decompress(const std::string &raw) {
    z_stream inflate_stream;
    memset(&inflate_stream, 0, sizeof(inflate_stream));

    // TODO: reuse z_streams
    if (deflateInit2(&deflate_stream, Z_DEFAULT_COMPRESSION,
                     Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
        throw std::runtime_error("failed to initialize inflate");
    }

    inflate_stream.next_in = reinterpret_cast<Bytef *>(const_cast<char *>(raw.data()));
    inflate_stream.avail_in = uInt(raw.size());

    std::string result;
    char out[15384];

    int code;
    do {
        inflate_stream.next_out = reinterpret_cast<Bytef *>(out);
        inflate_stream.avail_out = sizeof(out);
        code = inflate(&inflate_stream, 0);
        // result.append(out, sizeof(out) - inflate_stream.avail_out);
        if (result.size() < inflate_stream.total_out) {
            result.append(out, inflate_stream.total_out - result.size());
        }
    } while (code == Z_OK);

    inflateEnd(&inflate_stream);

    if (code != Z_STREAM_END) {
        throw std::runtime_error(inflate_stream.msg ? inflate_stream.msg : "decompression error");
    }

    return result;
}


// gzip压缩
std::string compress(const std::string &raw) {
    z_stream deflate_stream;
    memset(&deflate_stream, 0, sizeof(deflate_stream));

    // TODO: reuse z_streams
    if (deflateInit2(&deflate_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
        throw std::runtime_error("failed to initialize deflate");
    }

    deflate_stream.next_in = reinterpret_cast<Bytef *>(const_cast<char *>(raw.data()));
    deflate_stream.avail_in = uInt(raw.size());

    std::string result;
    char out[16384];

    int code;
    do {
        deflate_stream.next_out = reinterpret_cast<Bytef *>(out);
        deflate_stream.avail_out = sizeof(out);
        code = deflate(&deflate_stream, Z_FINISH);
        if (result.size() < deflate_stream.total_out) {
            // append the block to the output string
            result.append(out, deflate_stream.total_out - result.size());
        }
    } while (code == Z_OK);

    deflateEnd(&deflate_stream);

    if (code != Z_STREAM_END) {
        throw std::runtime_error(deflate_stream.msg);
    }

    return result;
}


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Copyright © 1999-2019, lu16.com, All Rights Reserved