《QT从基础到进阶·七十二》基于Qt开发的文件保险柜工具并支持文件各种加密和解密

1、概述
源码放在文章末尾

该项目实现了文件各种加密和解密的功能,能够有效的保障文件的安全,主要包含如下功能:
1、支持所有 AES 密钥长度;
AES_128
AES_192
AES_256
2、支持ECB、CBC、CFB、OFB四种模式;
3、支持ZERO、PKCS7、ISO三种填充方式;
4、支持md5文件损毁检测
5、支持输入任意长度密钥进行加解密;
6、将.bmp格式图片加密后可正常打开图片,不破坏图片格式。

项目截图效果如下所示:
(1)文件加密
在这里插入图片描述
(2)文件解密
在这里插入图片描述

(3)bmp图片加密
在这里插入图片描述

项目部分代码如下所示:

#ifndef FILEENCRYPTION_H
#define FILEENCRYPTION_H#include <QObject>
#include "qaesencryption.h"class FileEncryption : public QObject
{Q_OBJECT
public:explicit FileEncryption(QObject *parent = nullptr);void setFile(const QString& strIn, const QString& strOut);void setKey(const QByteArray& key);void setEncryption(bool flag);void setAESParameter(QAESEncryption::Aes aes, QAESEncryption::Mode mode, QAESEncryption::Padding padding);void stop();                        // 停止signals:void start();                       // 开始void showLog(QString log);          // 日志private:void startEncryption();void encryption();void decrypt();bool readFile(const QString& fileName);void dataOperation();void check();bool writeFile(const QString& fileName);void clear();private:QString m_strIn;          // 输入文件路径QString m_strOut;         // 输出文件路径QString m_fileSuffix;     // 文件后缀QByteArray m_key;         // 密钥QByteArray m_iv;          // 偏移bool m_encryption = true;QAESEncryption::Aes m_aes;QAESEncryption::Mode m_mode;QAESEncryption::Padding m_padding;QByteArray m_dataIn;     // 输入内容QByteArray m_dataOut;    // 输出内容QByteArray m_md5;        // MD5值QByteArray m_head;       // bmp图片的文件信息
};#endif // FILEENCRYPTION_H
#include "fileencryption.h"#include <QDir>
#include <QFileInfo>
#include <QImage>
#include <qcryptographichash.h>
#include <qdebug.h>
#include <qfile.h>
#include <qthread.h>FileEncryption::FileEncryption(QObject *parent) : QObject(parent)
{connect(this, &FileEncryption::start, this, &FileEncryption::startEncryption);for(int i = 0; i < 16; i++){m_iv.append((uchar)i);}
}/*** @brief         设置输入输出文件路径* @param strIn   输入文件路径* @param strOut  输出文件路径*/
void FileEncryption::setFile(const QString& strIn, const QString& strOut)
{if(!strIn.isEmpty() && !strOut.isEmpty()){this->m_strIn = strIn;this->m_strOut = strOut;QFileInfo info(strIn);m_fileSuffix = info.suffix();}
}/*** @brief      设置使用的密钥* @param key*/
void FileEncryption::setKey(const QByteArray &key)
{this->m_key = key;
}/*** @brief        设置加密或者解密* @param flag   true:加密 false:解密*/
void FileEncryption::setEncryption(bool flag)
{this->m_encryption = flag;
}/*** @brief           设置AES加解密参数* @param aes* @param mode* @param padding*/
void FileEncryption::setAESParameter(QAESEncryption::Aes aes, QAESEncryption::Mode mode, QAESEncryption::Padding padding)
{this->m_aes = aes;this->m_mode = mode;this->m_padding = padding;
}/*** @brief 加解密操作*/
void FileEncryption::startEncryption()
{clear();emit showLog("开始输入原文件!");if(readFile(m_strIn)){emit showLog("文件读取完成!");if(m_encryption){encryption();}else{decrypt();}if(writeFile(m_strOut)){emit showLog("数据写入成功!");}clear();}else{emit showLog("输入文件读取失败!");}
}/*** @brief 加密*/
void FileEncryption::encryption()
{QAESEncryption encryption(m_aes, m_mode, m_padding);emit showLog("开始加密!");if(m_mode == QAESEncryption::ECB){m_dataOut.append(encryption.encode(m_dataIn, m_key));}else{m_dataOut.append(encryption.encode(m_dataIn, m_key, m_iv));}m_dataOut.insert(0, m_head);m_dataOut.append(m_md5);emit showLog("加密完成,开始写入!");}/*** @brief  解密*/
void FileEncryption::decrypt()
{QAESEncryption encryption(m_aes, m_mode, m_padding);emit showLog("开始解密!");if(m_mode == QAESEncryption::ECB){m_dataOut.append(encryption.decode(m_dataIn, m_key));}else{m_dataOut.append(encryption.decode(m_dataIn, m_key, m_iv));}m_dataOut = encryption.removePadding(m_dataOut);        // 移除填充数据m_dataOut.insert(0, m_head);emit showLog("解密完成,开始写入!");check();
}/*** @brief           读取文件内容* @param fileName*/
bool FileEncryption::readFile(const QString &fileName)
{QFile file(fileName);if(file.open(QIODevice::ReadOnly)){m_dataIn = file.readAll();file.close();dataOperation();return true;}else{emit showLog(QString("%1打开失败!").arg(fileName));return false;}
}/*** @brief 操作数据内容*/
void FileEncryption::dataOperation()
{// 获取md5值if(m_encryption){m_md5 = QCryptographicHash::hash(m_dataIn, QCryptographicHash::Md5).toHex();}else                  // 解密时读取md5值{m_md5 = m_dataIn.mid(m_dataIn.count() - 32, 32);m_dataIn.remove(m_dataIn.count() - 32, 32);}// 读取bmo文件头信息if(m_fileSuffix.compare("bmp", Qt::CaseInsensitive) == 0){m_head = m_dataIn.mid(0, 54);        // bmp文件头:共14字节;位图信息头:共40字节;m_dataIn.remove(0, 54);}
}/*** @brief  使用md5校验文件是否损毁*/
void FileEncryption::check()
{QByteArray arr = QCryptographicHash::hash(m_dataOut, QCryptographicHash::Md5).toHex();if(arr == m_md5){emit showLog("文件未损毁!");}else{emit showLog("文件存在不同,可能已损毁!");}
}/*** @brief           写文件内容* @param fileName* @param data*/
bool FileEncryption::writeFile(const QString &fileName)
{QFileInfo info(fileName);QString filePath = info.absolutePath();QDir dir;if(!dir.exists(filePath)){dir.mkpath(filePath);}QFile file(fileName);if(file.open(QIODevice::WriteOnly)){file.write(m_dataOut);file.close();return true;}else{emit showLog(QString("%1打开失败!").arg(fileName));return false;}
}/*** @brief 清空数据*/
void FileEncryption::clear()
{m_dataIn.clear();m_dataOut.clear();m_head.clear();m_md5.clear();
}

源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/30276.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序学习(二):常用样式和组件

常用样式和组件 在小程序中不能使用HTML标签&#xff0c;也就没有DOM和BOM&#xff0c;同时仅仅支持部分CSS选择器。WXML 充当的就是类似 HTML 的角色&#xff0c;只不过在 WXML 中没有div、p、 span、img、a 等标签&#xff0c;在 WXML 中需要使用 小程序提供的 view、text 、…

MyBatis的配置文件,即:src->main->resources的配置

目录 1、properties 标签 1.1 mybatis-config.xml 1.2 db.properties 1.3 在SqlMapConfig.xml 中 引入数据库配置信息 2、typeAliases 标签 2.1 定义别名 2.2 使用别名 3、Mappers标签 作用&#xff1a;用来在核心配置文件中引入映射文件 引入方式&#xff0c;有以下…

AI 已经在污染互联网了。。赛博喂屎成为现实

大家好&#xff0c;我是程序员鱼皮。这两年 AI 发展势头迅猛&#xff0c;更好的性能、更低的成本、更优的效果&#xff0c;让 AI 这一曾经高高在上的技术也走入大众的视野&#xff0c;能够被我们大多数普通人轻松使用&#xff0c;无需理解复杂的技术和原理。 其中&#xff0c;…

爆赞!24年GitHub首本Python开发实战背记手册,标星果然百万名不虚传

Python (发音:[ paiθ(ə) n; (US) paiθɔn ] n. 蟒蛇&#xff0c;巨蛇 )&#xff0c;是一种面向对象的解释性的计算机程序设计语言&#xff0c;也是一种功能强大而完善的通用型语言&#xff0c;已经具有十多年的发展历史&#xff0c;成熟且稳定。Python 具有脚本语言中最丰富…

common.js和es6中模块引入的区别?

在JavaScript中&#xff0c;CommonJS 和 ES6&#xff08;也称为ECMAScript 2015或ES2015&#xff09;都提供了模块化的功能&#xff0c;但它们之间存在一些关键的差异。以下是它们之间在模块引入方面的主要区别&#xff1a; CommonJS&#xff08;例如 Node.js&#xff09; 同步…

新火种AI|实属罕见!四大AI顶流同台,有哪些关键信息值得关注?

作者&#xff1a;小岩 编辑&#xff1a;彩云 在有着“AI春晚”之称的2024年智源大会上&#xff0c;非常难得的一幕出现了&#xff1a;当下国内的四大AI顶流公司——月之暗面&#xff0c;百川智能&#xff0c;智谱AI&#xff0c;面壁智能齐聚一堂&#xff0c;十分罕见的同台了…

软考系规论文写作万能模板

在软考高级考试中&#xff0c;论文是必须要过的坎儿。在学习软考系规《系统规划与管理师》之前首先要明白一点&#xff1a;不是教材全部学完才开始去准备论文&#xff0c;其实在学习的过程中去准备论文&#xff0c;论文的质量会更高&#xff0c;主要有以下几方面原因&#xff1…

天地图 uniapp使用笔记

官网地址&#xff1a;天地图API 效果&#xff1a; <template><view><!-- 显示地图的DOM节点 --><view id"container" class"content"></view><!-- END --><!-- 数据显示 --><h3>城市名称(IP属地)&#x…

1.MySQL---分布式系统

分布式系统中生成唯一id的方法一: 分布式唯一id 时间戳机房编号/主机编号随机因子(指字符串拼接) 如果添加商品的速度比较慢,直接使用时间戳就够了 但是如果一个时间戳内,添加了多个商品, 添加的多个商品,是落在不同的主机上的,就可以保证同一时间内,添加到不同主机的商品编…

Fisnar Liquid Control 操作维修手LC Pump Manual Twinmixer Maintenance 中文

Fisnar Liquid Control 操作维修手LC Pump Manual Twinmixer Maintenance 中文

Jquery 正则匹配字母、数字、-

Jquery 正则匹配字母、数字、- Jquery正则方式一Jquery正则方式二 本文主要讲述页面日常开发过程中需要校验输入参数时&#xff0c;采用正则校验的方式的使用方法&#xff0c;一共有两种形式&#xff0c;其中本文用到的正则公式主要是匹配字母、数字、中横线如下 Jquery正则方式…

DAY03 HTML

文章目录 一 表格1. 表格的语法2. 表格的可选标记3. 不规则的单元格&#xff08;合并单元格&#xff09;4. 表格的属性5. 表格的大小 二 列表1. 有序列表2. 无序列表3. 属性4. 列表的嵌套5. 定义列表【了解】 三 表单(重点)1. 表单的语法2. 表单的控件分类3. input元素4. selec…

智慧工地系统源码,支持项目级、公司级、集团级多级权限划分,支持PC端、手机端

智慧工地的核心是数字化&#xff0c;它通过传感器、监控设备、智能终端等技术手段&#xff0c;实现对工地各个环节的实时数据采集和传输&#xff0c;如环境温度、湿度、噪音等数据信息&#xff0c;将数据汇集到云端进行处理和分析&#xff0c;生成各种报表、图表和预警信息&…

js遍历数组的方法?有什么区别?

JavaScript 提供了多种遍历数组的方法&#xff0c;每种方法都有其特定的用途和区别。以下是一些常用的遍历数组的方法及其区别&#xff1a; for 循环 传统的遍历数组的方式可以通过索引直接访问数组元素需要手动控制循环的开始、结束和循环变量 javascript复制代码 for (let i…

Deflate内部实现(LZ77无损压缩算法)超详细图解算法版~

无损压缩算法 第一阶段&#xff1a;重复消除 — LZ77无损压缩算法算法介绍举例压缩算法思路图解压缩过程 第二阶段&#xff1a;位减少huffman位减少 概览 Gzip Deflate 编码&#xff08;LZ77哈夫曼&#xff09; Brotli LZ77哈夫曼二阶上下文建模 Deflate 分两个阶段压缩数据…

【Linux】Centos升级到国产操作系统OpenAnolis

一、前言 Anolis OS 7生态上和依赖管理上保持跟CentOS7.x兼容&#xff0c;一键式迁移脚本centos2anolis.py&#xff0c;实现CentOS7.x到Anolis OS 7的平滑迁移 使用迁移脚本前需要注意如下事项&#xff1a; 迁移涉及到软件包的重新安装&#xff0c;是不可逆过程&#xff0c;…

springboot redission 分布式锁

Spring Boot中使用Redisson实现分布式锁的方法如下&#xff1a; 1. 首先&#xff0c;需要在项目中引入Redisson依赖。在pom.xml文件中添加以下依赖&#xff1a; xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson<…

基于SpringBoot的社区医院管理服务系统

开头语&#xff1a;你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架 工具&#xff1a;Eclipse&#xff0c;Navicat&#xff0c;Maven…

Python数据分析入门指南

Python作为一种多功能编程语言&#xff0c;因其简洁易读的语法和强大的库支持&#xff0c;已经成为数据分析领域的热门工具。本文将介绍如何使用Python进行基本的数据分析&#xff0c;包括数据的导入、清洗、处理和可视化。 环境搭建 在开始之前&#xff0c;确保你已经安装了…

拉取其他分支的代码

我在slx分支上&#xff0c;如何把master的分支拉取到slx分支上 结论&#xff1a;git pull origin master 详细解释 要将 master 分支的最新更改合并到 slx 分支上&#xff0c;你可以按照以下步骤进行操作&#xff1a; 使用命令行进行合并 确保在 slx 分支上 在开始之前&…