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;
}
} 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;
}
} if(last_ret != 0) {
return -3;
} return 0;
} } // namespace util

zstd c++ string 压缩&解压的更多相关文章

  1. 对称加密之AES、压缩解压以及压缩加密解密解压综合实战

    AES 压缩解压 压缩加密解密解压 对称加密: 就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密.密钥是控制加密及解密过程的指令.算法是一组规则,规定如何进行加密和解密.   因此加密的安 ...

  2. 分享一个ASP.NET 文件压缩解压类 C#

    需要引用一个ICSharpCode.SharpZipLib.dll using System; using System.Collections.Generic; using System.Linq; ...

  3. .NET使用ICSharpCode.SharpZipLib压缩/解压文件

    SharpZipLib是国外开源加压解压库,可以方便的对文件进行加压/解压 1.下载ICSharpCode.SharpZipLib.dll,并复制到bin目录下 http://www.icsharpc ...

  4. 使用SevenZipSharp压缩/解压7z格式

    7z格式采用的LZMA算法,号称具有现今最高压缩率.笔者在nuget上搜索7z,在搜索结果中最终选择了SevenZipSharp来进行压缩/解压.不得不说,SevenZipSharp的API设计得非常 ...

  5. 【.Net Core】ZipFile类--文件的压缩解压

    NuGet引用官网自带的System.IO.Compression.ZipFile; var filename = "测试压缩解压文件"; var path = Directory ...

  6. WebAPI性能优化之压缩解压

    有时候为了提升WebAPI的性能,减少响应时间,我们会使用压缩和解压,而现在大多数客户端浏览器都提供了内置的解压支持.在WebAPI请求的资源越大时,使用压缩对性能提升的效果越明显,而当请求的资源很小 ...

  7. (转载)C#压缩解压zip 文件

    转载之: C#压缩解压zip 文件 - 大气象 - 博客园http://www.cnblogs.com/greatverve/archive/2011/12/27/csharp-zip.html C# ...

  8. 字符串GZIP压缩解压

    c# /// <summary> /// 字符串压缩解压 /// </summary> public class Zipper { public static string C ...

  9. Java压缩/解压.zip、.tar.gz、.tar.bz2(支持中文)

    本文介绍Java压缩/解压.zip..tar.gz..tar.bz2的方式. 对于zip文件:使用java.util.zip.ZipEntry 和 java.util.zip.ZipFile,通过设置 ...

随机推荐

  1. arm-linux openssl移植

    从openssl官网下载openssl https://www.openssl.org/source/ 1.解压到linux中 2. ./config no-asm shared --prefix=$ ...

  2. [LeetCode题解]109. 有序链表转换二叉搜索树 | 快慢指针 + 递归

    题目描述 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定的有序链表: ...

  3. [head first 设计模式] 第一章 策略模式

    [head first 设计模式] 第一章 策略模式 让我们先从一个简单的鸭子模拟器开始讲起. 假设有个简单的鸭子模拟器,游戏中会出现各种鸭子,此系统的原始设计如下,设计了一个鸭子超类,并让各种鸭子继 ...

  4. MYSQL渗透测试

    部分来源于:先知社区 MYSQL-getshell篇 通过日志getshell 查看日志的物理路径(绝对路径) show variables like '%general%'; 打开日志记录内容 se ...

  5. 【P1972】HH的项链——树状数组+询问离线

    (题面摘自luogu) 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集 ...

  6. GitHub 上 1.3k Star 的 strman-java 项目有值得学习的地方吗?源码视角

    大家好,我是沉默王二. 很多初学编程的同学,经常给我吐槽,说:"二哥,你在敲代码的时候会不会有这样一种感觉,写着写着看不下去了,觉得自己写出来的代码就好像屎一样?" 这里我必须得说 ...

  7. wsgi_uwsgi_nginx

    1.一些重要概念 https://www.cnblogs.com/xiaonq/p/8932266.html 1.1 web容器 什么是web容器 1.web容器是帮助我们部署java.php.pyt ...

  8. C和指针---结构和联合

    一.结构 1.C提供了两种类型的聚合数据类型---数组.结构.数组是相同类型的元素集合,它的每个元素长度相同,故可以通过下标引用或指针间接访问来选择的;而结构可以把不同类型的值存储在一起,由于结构的成 ...

  9. 浅尝 Elastic Stack (四) Logstash + Beats 读取 Spring Boot 日志

    一.Spring Boot 日志配置 采用 Spring Boot 默认的 Logback: <?xml version="1.0" encoding="UTF-8 ...

  10. 20200221_python虚拟环境在Windows下安装配置_virtualenv不是内部或外部命令也不是可运行的程序或批处理文件

    1. 使用管理员启动命令行; 2. 安装虚拟环境 a)      .\pip install virtualenv  -i https://pypi.douban.com/simple/ b)     ...