• zstd c++ string 压缩&解压


    zstd 简介

    维基百科定义:

    Zstandard(或Zstd)是由Facebook的Yann Collet开发的一个无损数据压缩算法。该名称也指其C语言的参考实现。第1版的实现于2016年8月31日发布为自由软件
    设计Zstandard的目的是提供一个类似于DEFLATE算法的压缩比,但更快,特别是解压缩快的算法。

    1. 它的压缩级别从负5级(最快)到22级(压缩速度最慢,但是压缩比最高)可以调节。
    2. zstd包里面有压缩和解压缩的并行(多线程)实现。从1.3.2版本(2017年10月)开始,zstd 有选择地实现非常长的搜索和重复数据消除(--long,128MiB窗口),类似于rzip或lrzip。
    3. 压缩速度在最快和最慢级别之间可以相差20倍或更多,而解压缩速度统统很快,在最快和最慢级别之间相差不到20%。
    4. Zstandard命令行有一个“自适应”(--adapt)模式,根据I/O条件改变压缩级别,主要是写入输出的速度。
    5. Zstd在其最大压缩级别下的压缩比接近lzma、lzham和ppmx,并且比lza或bzip2性能更好。
    6. Zstandard达到了当前的Pareto边界,因为它解压缩的速度比任何其他当前可用的算法都要快,并且有类似的或者更好的压缩比。
    7. 字典对小文件的压缩比有很大的影响,所以Zstandard可以使用用户提供的压缩字典。它还提供了一种训练模式,能够从一组样本生成一个字典。
    8. 特别是,可以加载一个字典来处理文件之间具有冗余的大型文件集,但不一定在每个文件(例如日志文件)内。

    c++中应用

    最常见的就是对于字符串的压缩,下边给出字符串源码

    转载请注明出处,谢谢
    欢迎访问我的github https://github.com/hashyong/zstd_util

    //
    // -*- coding: utf-8-unix; -*-
    //  Copyright (c) 2020 Tencent, Inc.
    //     All rights reserved.
    //
    // Date:   2020/11/30 13:45
    // File:   zstd.cc
    // Desc:
    //
    
    #include "util.h"
    
    #include "third_party/zstd/zstd.h"
    
    namespace util {
    
    int Util::CompressString(const string& src, string& dst, int compressionlevel) {
      size_t const cBuffSize = ZSTD_compressBound(src.size());
      dst.resize(cBuffSize);
      auto dstp = const_cast<void*>(static_cast<const void*>(dst.c_str()));
      auto srcp = static_cast<const void*>(src.c_str());
      size_t const cSize = ZSTD_compress(dstp, cBuffSize, srcp, src.size(), compressionlevel);
      auto code = ZSTD_isError(cSize);
      if (code) {
        return code;
      }
      dst.resize(cSize);
      return code;
    }
    
    int Util::DecompressString(const string& src, string& dst) {
      size_t const cBuffSize = ZSTD_getFrameContentSize(src.c_str(), src.size());
    
      if (0 == cBuffSize) {
        return cBuffSize;
      }
    
      if (ZSTD_CONTENTSIZE_UNKNOWN == cBuffSize) {
        return StreamDecompressString(src, dst);
      }
    
      if (ZSTD_CONTENTSIZE_ERROR == cBuffSize) {
        return -2;
      }
    
      dst.resize(cBuffSize);
      auto dstp = const_cast<void*>(static_cast<const void*>(dst.c_str()));
      auto srcp = static_cast<const void*>(src.c_str());
      size_t const cSize = ZSTD_decompress(dstp, cBuffSize, srcp, src.size());
      auto code = ZSTD_isError(cSize);
      if (code) {
        return code;
      }
      dst.resize(cSize);
      return code;
    }
    
    int Util::StreamCompressString(const string& src, string& dst, int compressionlevel) {
      size_t const buffInSize = ZSTD_CStreamInSize();
      string buffInTmp;
      buffInTmp.reserve(buffInSize);
      auto buffIn = const_cast<void*>(static_cast<const void*>(buffInTmp.c_str()));
    
      auto buffOutSize = ZSTD_CStreamOutSize();
      string buffOutTmp;
      buffOutTmp.reserve(buffOutSize);
      auto buffOut = const_cast<void*>(static_cast<const void*>(buffOutTmp.c_str()));
    
      ZSTD_CCtx* const cctx = ZSTD_createCCtx();
      ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compressionlevel);
    
      size_t const toRead = buffInSize;
      auto local_pos = 0;
      auto buff_tmp = const_cast<char*>(buffInTmp.c_str());
      for (;;) {
        size_t read = src.copy(buff_tmp, toRead, local_pos);
        local_pos += read;
    
        int const lastChunk = (read < toRead);
        ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;
    
        ZSTD_inBuffer input = {buffIn, read, 0};
        int finished;
    
        do {
          ZSTD_outBuffer output = {buffOut, buffOutSize, 0};
          size_t const remaining = ZSTD_compressStream2(cctx, &output, &input, mode);
          dst.insert(dst.end(), buffOutTmp.begin(), buffOutTmp.begin() + output.pos);
          finished = lastChunk ? (remaining == 0) : (input.pos == input.size);
        } while (!finished);
    
        if (lastChunk) {
          break;
        }
      }
    
      ZSTD_freeCCtx(cctx);
    
      return 0;
    }
    
    int Util::StreamDecompressString(const string& src, string& dst, int compressionlevel) {
      size_t const buffInSize = ZSTD_DStreamInSize();
      string buffInTmp;
      buffInTmp.reserve(buffInSize);
      auto buffIn = const_cast<void*>(static_cast<const void*>(buffInTmp.c_str()));
    
      auto buffOutSize = ZSTD_DStreamOutSize();
      string buffOutTmp;
      buffOutTmp.reserve(buffOutSize);
      auto buffOut = const_cast<void*>(static_cast<const void*>(buffOutTmp.c_str()));
    
      ZSTD_DCtx* const dctx = ZSTD_createDCtx();
    
      size_t const toRead = buffInSize;
      size_t read;
      size_t last_ret = 0;
      size_t local_pos = 0;
      auto buff_tmp = const_cast<char*>(buffInTmp.c_str());
    
      while ((read = src.copy(buff_tmp, toRead, local_pos))) {
        local_pos += read;
        ZSTD_inBuffer input = {buffIn, read, 0};
        while (input.pos < input.size) {
          ZSTD_outBuffer output = {buffOut, buffOutSize, 0};
          size_t const ret = ZSTD_decompressStream(dctx, &output, &input);
          dst.insert(dst.end(), buffOutTmp.begin(), buffOutTmp.begin() + output.pos);
          last_ret = ret;
        }
      }
    
      ZSTD_freeDCtx(dctx);
    
      if(last_ret != 0) {
        return -3;
      }
    
      return 0;
    }
    
    }  // namespace util
    
    

    作者: fattycoder

    出处: https://www.cnblogs.com/fattyCoder/

    关于作者:挺喜欢写代码的

    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(564790073@qq.com)咨询.

  • 相关阅读:
    Delphi TWebBrowser[11] 读写html代码
    Nginx 配置反向代理
    清除git中缓存的凭证(用户名及密码)
    python 摄像头
    a 链接控制打开新窗口 无地址栏
    树形多级菜单数据源嵌套结构与扁平结构互转
    使用 git 的正确姿势
    JavaScript this
    JavaScript Scope Chain
    JavaScript Scope Context
  • 原文地址:https://www.cnblogs.com/fattyCoder/p/14135278.html
Copyright © 2020-2023  润新知