openssl3.2 - exp - zlib
文章目录
- openssl3.2 - exp - zlib
- 概述
- 笔记
- 命令行实现
- 程序实现
- 备注 - 压缩时无法base64
- 压缩时无法带口令压缩
- 实现 - 对buffer进行压缩和解压缩
- 测试效果
- 工程实现
- main.cpp
- COsslZlibBuffer.h
- COsslZlibBuffer.cpp
- 总结
- END
openssl3.2 - exp - zlib
概述
客户端和服务端进行数据交换时,如果压缩一下要交互的数据,可以节省带宽。
如果数据是文本型, 压缩率特别大。
以前用zlib库单独实验过,写起来还挺麻烦的。
正好这次已经将zlib特性加入了openssl(openssl3.2 - 编译 - zlib.dll不要使用绝对路径), 试一下用openssl来压缩/解压缩数据方便不?
笔记
命令行实现
// openssl zip help
openssl zlib --help// zip
openssl zlib -e -in test.txt -out test.txt.zlib -pass pass:my_pwd// unzip
openssl zlib -d -in test.txt.zlib -out test.txt.zlib.unzlib -pass pass:my_pwd
程序实现
先看一下openssl.exe的实现
备注 - 压缩时无法base64
如果选了zlib, 就不能选base64.
如果想zlib后,再base64, 需要单独对输出结果进行base64(https://lostspeed.blog.csdn.net/article/details/136881319).
if (do_zlib)base64 = 0;
压缩时无法带口令压缩
压缩时口令不起作用,因为可以不带口令解开。
openssl zlib -d -in test.txt.zlib -out test.txt.zlib.unzlib
如果想将压缩后的内容加密,需要自己单独对压缩后的内容加密。
实现 - 对buffer进行压缩和解压缩
测试效果
org:
0000 - 68 65 6c 6c 6f 20 6f 70-65 6e 73 73 6c 33 2e 32 hello openssl3.2
0010 - 20 7a 6c 69 62 0a zlib.
zip:
0000 - 78 9c cb 48 cd c9 c9 57-c8 2f 48 cd 2b 2e ce 31 x..H...W./H.+..1
0010 - d6 33 52 a8 ca c9 4c e2-02 00 5e 4e 07 a7 .3R...L...^N..
unzip:
0000 - 68 65 6c 6c 6f 20 6f 70-65 6e 73 73 6c 33 2e 32 hello openssl3.2
0010 - 20 7a 6c 69 62 0a zlib.
free mem_hook map, g_mem_hook_map.size() = 0, no openssl API call memory leak
工程实现
test prj is exp034_zlib
main.cpp
/*!
* \file main.cpp
*/#include "ossl/my_openSSL_lib_v1.1.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>#include <stdlib.h>
#include <stdio.h>
#include <assert.h>#include "COsslZlibBuffer.h"void my_openssl_app();int main(int argc, char** argv)
{setvbuf(stdout, NULL, _IONBF, 0); // 清掉stdout缓存, 防止调用printf时阻塞mem_hook();my_openssl_app();mem_unhook();return 0;
}void my_openssl_app()
{bool b_rc = false;int i_rc = 0;COsslZlibBuffer zlib;uint8_t szBuf[0x1000];int lenBuf = 0;uint8_t* pBufOut1 = NULL;int lenBufOut1 = 0;uint8_t* pBufOut2 = NULL;int lenBufOut2 = 0;strcpy((char*)szBuf, "hello openssl3.2 zlib\n");lenBuf = strlen((char*)szBuf);printf("org:\n");BIO_dump_fp(stdout, szBuf, lenBuf);b_rc = zlib.zip(szBuf, lenBuf, pBufOut1, lenBufOut1);assert(b_rc);printf("zip:\n");BIO_dump_fp(stdout, pBufOut1, lenBufOut1);b_rc = zlib.unzip(pBufOut1, lenBufOut1, pBufOut2, lenBufOut2);assert(b_rc);printf("unzip:\n");BIO_dump_fp(stdout, pBufOut2, lenBufOut2);assert(lenBufOut2 == lenBuf);i_rc = memcmp(szBuf, pBufOut2, lenBuf);assert(0 == i_rc);if (NULL != pBufOut1){OPENSSL_free(pBufOut1);pBufOut1 = NULL;}if (NULL != pBufOut2){OPENSSL_free(pBufOut2);pBufOut2 = NULL;}
}
COsslZlibBuffer.h
//! \file COsslZlibBuffer.h#ifndef __C_OSSL_ZLIB_BUFFER_H__
#define __C_OSSL_ZLIB_BUFFER_H__#include <stdlib.h>
#include <stdio.h>
#include <cstdint> // for uint8_t#ifndef IN
#define IN
#endif // !IN#ifndef OUT
#define OUT
#endif // !OUT#include "openssl/bio.h"class COsslZlibBuffer
{
public:COsslZlibBuffer();virtual ~COsslZlibBuffer();// 出参指针调用者负责释放(OPENSSL_free())bool zip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut);bool unzip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut);private:bool zipOpt(bool isZip, IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut);size_t bio_get_length(BIO* bio);bool bio_to_buf(BIO* bio, uint8_t*& pBuf, int& lenBuf);
};#endif // #ifndef __C_OSSL_ZLIB_BUFFER_H__
COsslZlibBuffer.cpp
//! \file COsslZlibBuffer.cpp#include "COsslZlibBuffer.h"#include "openssl/bio.h"
#include "openssl/comp.h"COsslZlibBuffer::COsslZlibBuffer()
{}COsslZlibBuffer::~COsslZlibBuffer()
{}bool COsslZlibBuffer::zip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut)
{return zipOpt(true, pBuf, lenBuf, pBufOut, lenBufOut);
}bool COsslZlibBuffer::unzip(IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut)
{return zipOpt(false, pBuf, lenBuf, pBufOut, lenBufOut);
}bool COsslZlibBuffer::zipOpt(bool isZip, IN uint8_t* pBuf, IN int lenBuf, OUT uint8_t*& pBufOut, OUT int& lenBufOut)
{bool b_rc = false;BIO* bio_zip = NULL;BIO* bio_in = NULL;BIO* bio_out = NULL;BIO* bio_read = NULL;BIO* bio_write = NULL;uint8_t szBuf[0x1000];int iCntRead = 0;int iCntWasWrite = 0;do {if ((NULL == pBuf) || (lenBuf <= 0)){break;}lenBufOut = 0;bio_zip = BIO_new(BIO_f_zlib());if (NULL == bio_zip){break;}bio_in = BIO_new_mem_buf(pBuf, lenBuf);if (NULL == bio_in){break;}bio_out = BIO_new(BIO_s_mem());if (NULL == bio_out){break;}if (isZip){bio_read = bio_in;bio_write = BIO_push(bio_zip, bio_out); // write to bio link header, out form bio link tail}else {bio_read = BIO_push(bio_zip, bio_in);bio_write = bio_out;}do {iCntRead = BIO_read(bio_read, szBuf, (int)sizeof(szBuf));if (iCntRead <= 0){break;}iCntWasWrite = BIO_write(bio_write, szBuf, iCntRead);if (iCntWasWrite != iCntRead){goto END;}} while (true);if (!BIO_flush(bio_write)){break;}// 如果读bio_write, 得到的是写入的数据, 而不是处理完的输出数据if (!bio_to_buf(bio_out, pBufOut, lenBufOut)){break;}/*do_zlib = 1;enc = 1;saltlen = PKCS5_SALT_LEN;dgst = (EVP_MD *)EVP_sha256();iter = 1;if (do_zlib)base64 = 0;BIO *bzl = NULL;bzl = BIO_new(BIO_f_zlib()wbio = BIO_push(bzl, wbio);while (BIO_pending(rbio) || !BIO_eof(rbio)) {inl = BIO_read(rbio, (char *)buff, bsize);if (inl <= 0)break;if (!streamable && !BIO_eof(rbio)) {// BIO_printf(bio_err, "Unstreamable cipher mode\n");// goto end;//}//if (BIO_write(wbio, (char*)buff, inl) != inl) {// BIO_printf(bio_err, "error writing output file\n");// goto end;//}//if (!streamable)//break;// }BIO_flush(wbio)if (enc)wbio = BIO_push(bzl, wbio);elserbio = BIO_push(bzl, rbio);*/b_rc = true;} while (false);END:if (NULL != bio_read){BIO_free_all(bio_read);bio_read = NULL;}if (NULL != bio_write){BIO_free_all(bio_write);bio_write = NULL;}return b_rc;
}size_t COsslZlibBuffer::bio_get_length(BIO* bio)
{size_t bio_length = 0;do {if (NULL == bio){break;}// BIO_seek(bio, 0);bio_length = BIO_ctrl_pending(bio);} while (false);return bio_length;
}bool COsslZlibBuffer::bio_to_buf(BIO* bio, uint8_t*& pBuf, int& lenBuf)
{bool b_rc = false;int i_rc = 0;do {if (NULL == bio){break;}lenBuf = (int)bio_get_length(bio);pBuf = (uint8_t*)OPENSSL_malloc(lenBuf + 1);if (NULL == pBuf){break;}pBuf[lenBuf] = '\0';i_rc = BIO_read(bio, pBuf, lenBuf);BIO_seek(bio, 0); // ! 读完了, 将数据读指针恢复.b_rc = (i_rc == lenBuf);} while (false);return b_rc;
}
总结
用openssl做zip操作比直接用zlib库操作方便多了。
openssl的封装真优秀。
END
相关文章:

openssl3.2 - exp - zlib
文章目录 openssl3.2 - exp - zlib概述笔记命令行实现程序实现备注 - 压缩时无法base64压缩时无法带口令压缩实现 - 对buffer进行压缩和解压缩测试效果工程实现main.cppCOsslZlibBuffer.hCOsslZlibBuffer.cpp总结END openssl3.2 - exp - zlib 概述 客户端和服务端进行数据交换…...

【故事】无人机学习之旅
今天是清明假期最后一天,晚上在看无人机的东西,翻到了欣飞鸽的知乎主页,读了他的一些文章。虽不曾相识,但感觉我们有很多相似的经历,也想记录一下自己的无人机学习之旅。 青铜:从使用开源飞控开始 我在大…...

torch.mean()的使用方法
对一个三维数组的每一维度进行操作 1,dim0 a torch.Tensor([0, 1, 2, 3, 4, 5,6,7]).view(2, 2, 2) print(a) mean torch.mean(a, 0) print(mean, mean.shape) 输出结果: tensor([[[0., 1.], [2., 3.]], [[4., 5.], [6., 7.]]]) tensor([[2., …...

windows安装Redis,Mongo,ES并快速基本掌握开发流程
前言 这里只是一些安装后的基础操作,后期会学习更加深入的操作 基础操作 前言RedisRedis启动idea集成Redisjedis技术 Mongodbwindows版Mongodb的安装idea整合Mongodb ES(Elasticsearch)ESwindows下载ES文档操作idea整合ES低级别ES整合高级别ES整合 Redis Redis是…...

ruoyi-nbcio-plus基于vue3的flowable的自定义业务提交申请组件的升级修改
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码:…...

掌握网络抓取技术:利用RobotRules库的Perl下载器一览小红书的世界
引言 在信息时代的浪潮下,人们对于获取和分析海量网络数据的需求与日俱增。网络抓取技术作为满足这一需求的关键工具,正在成为越来越多开发者的首选。而Perl语言,以其卓越的文本处理能力和灵活的特性,脱颖而出,成为了…...

典型新能源汽车热管理系统方案分析
目前行业具有代表性的热管理系统有PTC电加热方案、热泵方案(特斯拉八通阀热泵、吉利直接式热泵)、威马的柴油加热方案以及以理想为代表的插电式混动车方案。 小鹏P7整车热管理方案分析(PTC电加热方案) 小鹏P7作为小鹏汽车的第2款…...

使用Docker部署开源项目FreeGPT35来免费调用ChatGPT3.5 API
Vercel部署FreeGPT35有严重限制,玩玩就好,真用还是得docker。 限制原因: Vercel的流式响应并不是一开始写流,客户端就能立刻收到响应流,而是先写到一个缓冲区,当流关闭才一股脑的流式响应回来(不是实时流) 因此导致: …...

《Linux运维实战:Kylin V10操作系统开启安装软件保留缓存设置》
总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:Linux运维实战总结 一、操作步骤 1、改系统/etc/yum.conf配置文件,开启安装软件保留缓存设置 [rootecs-90c2-0003 ~]# vim /etc/yum.…...

视频生成技术:从GAN到Latte
GANs Diffusion Model...

机器学习中的激活函数
激活函数存在的意义: 激活函数决定了某个神经元是否被激活,当这个神经元接收到的信息是有用或无用的时候,激活函数决定了对这个神经元接收到的信息是留下还是抛弃。如果不加激活函数,神经元仅仅做线性变换,那么该神经网…...

LinuxAndroid: 旋转编码器input输入事件适配(旋转输入)
rk3588s: 旋转编码器input输入事件适配 基于Android 12 kernel-5.10版本 参考文档: https://blog.csdn.net/szembed/article/details/131551950 Linux 输入设备调试详解(零基础开发)Rotary_Encoder旋转编码器驱动 通用GPIO为例 挂载input输…...

机器学习和深度学习-- 李宏毅(笔记与个人理解)Day10
Day 10 Genaral GUidance training Loss 不够的case Loss on Testing data over fitting 为什么over fitting 留到下下周哦~~ 期待 solve CNN卷积神经网络 Bias-Conplexiy Trade off cross Validation how to split? N-fold Cross Validation mismatch 这节课总体听下来比较…...

perl 交叉编译
前言 Perl是一种高级、通用、解释型、动态的编程语言。Perl设计的初衷是为了更好地处理文本处理任务,但随着时间的发展,现在它已经变成了一种强大的一般目的编程语言。Perl支持面向过程和面向对象的编程风格。 Perl的特点: 强大的字符串处…...

浅谈.版本管理工具
定义: 版本控制是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。 特点: 1、方便用于管理多人协同开发项目 2、并行开发,可实现跨区…...

【汇编语言实战】已知10个整数求最大值
C语言描述该程序流程: #include <stdio.h> int main() {int a[]{11,33,23,54,12,51,2,4,34,45};int maxa[0];for(int i1;i<9;i){if(a[i]>max){maxa[i];}}printf("%d",max); }汇编语言: include irvine32.inc .data arr dword 11…...

在 CentOS 7 上安装 Redis
在 CentOS 7 上安装 Redis 可以通过几个简单的步骤完成。以下是一种常用的方法: 更新系统: 在安装任何新软件之前,最好先更新系统的软件包列表,以确保安装的软件版本是最新的。可以使用以下命令来更新: sudo yum up…...

『51单片机』蜂鸣器
🚩 WRITE IN FRONT 🚩 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四" 🔎🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…...

计算机视觉 | 基于二值图像数字矩阵的距离变换算法
Hi,大家好,我是半亩花海。本实验基于 OpenCV 实现了二值图像数字矩阵的距离变换算法。首先生成一个 480x480 的黑色背景图像(定义黑色为0,白色为1),在其中随机选择了三个白色像素点作为距离变换的原点&…...

Arcgis windows webadaptor配置
注意windows下安装细节 1、电脑必须添加限定域名及dns后缀。 准备工作 a、安装webadaptor,获取jar文件 b、tomcat中部署两个jar,名字不相同,一个用server配置,一个用于portal配置 c、geoserver用来配置server d、geoscene用来配置…...

对接阿里云实时语音转文字的思路
将上述概念转化为详细代码需要一定的步骤。这里,我们将根据之前讨论的服务划分,创建一个简化的框架来模拟这个流程。注意,由于空间限制和简化目的,某些实现细节会被省略或简化,你可能需要根据实际情况进行调整。 1. 配…...

如何转行成为产品经理?
转行NPDP也是很合适的一条发展路径,之后从事新产品开发相关工作~ 一、什么是NPDP? NPDP 是产品经理国际资格认证,美国产品开发与管理协会(PDMA)发起的,是目前国际公认的唯一的新产品开发专业认证ÿ…...

SpringCloudAlibaba-整合nacos(二)
目录地址: SpringCloudAlibaba整合-CSDN博客 一、nacos服务部分 1.下载nacos,并执行数据库脚本:nacos-mysql.sql 2.修改配置文件,配置mysql 3.启动nacos ./startup.sh -m standalone 4.访问:http://127.0.0.1:884…...

STM32H7通用定时器计数功能的使用
目录 概述 1 STM32定时器介绍 1.1 认识通用定时器 1.2 通用定时器的特征 1.3 递增计数模式 1.4 时钟选择 2 STM32Cube配置定时器时钟 2.1 配置定时器参数 2.2 配置定时器时钟 3 STM32H7定时器使用 3.1 认识定时器的数据结构 3.2 计数功能实现 4 测试案例 4.1 代码…...

信息系统项目管理师0044:IT治理方法与标准(3信息系统治理—3.1 IT治理—3.1.4 IT治理方法与标准)
点击查看专栏目录 文章目录 3.1.4 IT治理方法与标准1. ITSS中1T服务治理 3.1.4 IT治理方法与标准 考虑到IT治理对组织战略目标达成的重要性,国内外各类机构持续研究并沉淀IT治理相关的最佳实践方法、定义相关标准,这里面比较典型的是我国信息技术服务标准…...

探索Linux:在VMware虚拟机上安装Linux操作系统
探索Linux:在VMware虚拟机上安装Linux操作系统 在计算机领域,Linux操作系统以其稳定性、安全性和自由开源的特点备受青睐。通过在VMware虚拟机上安装Linux,您可以轻松体验Linux操作系统的强大功能。本文将详细介绍在VMware虚拟机上安装Linux…...

JavaScript进阶6之函数式编程与ES6ESNext规范
函数式编程 柯里化currycurrycompose示例:简化版展开写: debug示例一:示例二: 模板字符串css in js方案 箭头函数问题 生成器 generator应用场景 反射 Reflect 柯里化curry compose是curry的应用 在 lodash/fp underscore ramba …...

AcWing 1381. 阶乘
解题思路 最后一位数相乘的变化。注意:为什么不是ss%10,如果12 * 15, 12的最后一位时2, * 1530,则为3,问题是12*15180,为8,两 者不符,说明ss%10中的10要多加0. import j…...

Leetcode 394. 字符串解码
心路历程: 这道题看到括号直接想到栈,五分钟新题直接秒了,一开始以为需要两个栈分别存储数字和非数字,后来发现一个栈就够了,思路如图: 这道题考察的应该是队栈这两种数据结构的转换,因为每次…...

LeetCode - 1702. 修改后的最大二进制字符串
文章目录 解析AC CODE 题目链接:LeetCode - 1702. 修改后的最大二进制字符串 解析 详细题解:贪心,简洁写法(Python/Java/C/Go/JS/Rust) 思路很牛b。 简单来说我们需要想办法将0配对,将其变为10࿰…...