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

news2024/11/17 16:29:15

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.coloradmin.cn/o/1839110.html

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

相关文章

【学习】程序员资源网站

1 书栈网 简介&#xff1a;书栈网是程序员互联网IT开源编程书籍、资源免费阅读的网站&#xff0c;在书栈网你可以找到很多书籍、笔记资源。在这里&#xff0c;你可以根据热门收藏和阅读查看大家都在看什么&#xff0c;也可以根据技术栈分类找到对应模块的编程资源&#xff0c;…

构建高效的大数据量延迟任务调度平台

目录 引言系统需求分析系统架构设计 总体架构任务调度模块任务存储模块任务执行模块 任务调度算法 时间轮算法优先级队列分布式锁 数据存储方案 关系型数据库NoSQL数据库混合存储方案 容错和高可用性 主从复制数据备份与恢复故障转移 性能优化 水平扩展缓存机制异步处理 监控与…

深度解析“科技信贷”:构建科技支行的五维模型

科技信贷是指金融机构为支持科技创新、技术改造和设备更新等领域提供的专项信贷服务&#xff0c;旨在促进科技企业的发展和技术的进步。科技信贷在推动科技企业和创新项目发展方面具有重要作用&#xff0c;其特点在于提供定制化的金融支持&#xff0c;以满足科技创新链条中的融…

nginx+tomcat负载均衡、动静分离群集【☆☆☆☆☆】

Nginx是一款非常优秀的HTTP服务器软件&#xff0c;性能比tomcat更优秀&#xff0c;它支持高达50 000个并发连接数&#xff0c;拥有强大的静态资源处理能力&#xff0c;运行稳定&#xff0c;内存、CPU等系统资源消耗非常低。目前很多大型网站都应用Nginx服务器作为后端网站程序的…

项目四 OpenStack身份管理

任务一 理解身份服务 1.1 •Keystone的基本概念 • 认证 &#xff08; Authentication &#xff09; —— 确认 用户身份的过程&#xff0c;又称身份验证 。 • 凭证 &#xff08; Credentials &#xff09; —— 又 称凭据&#xff0c;是用于确认用户身份的数据 。 • 令牌 …

小林图解系统-二.硬件结构 2.5CPU是如何执行任务的?

CPU如何读取数据的&#xff1f; CPU访问L1 Cache速度比访问内存快100倍&#xff0c;有高速缓存的目的&#xff1a;把Cache作为CPU与内存之间的缓存层&#xff0c;减少对内存的访问频率 所有CPU Cache Line是CPU从内存读取数据到Cache的单位。 64字节 CPU加载数组里面连续的多…

【千帆AppBuilder】你有一封邮件待查收|未来的我,你好吗?欢迎体验AI应用《未来信使》

我在百度智能云千帆AppBuilder开发了一款AI原生应用&#xff0c;快来使用吧&#xff01;「未来信使」&#xff1a;https://appbuilder.baidu.com/s/Q1VPg 目录 背景人工智能未来的信 未来信使功能介绍Prompt组件 千帆社区主要功能AppBuilderModelBuilder详细信息 推荐文章 未来…

【APP移动端性能测试】第一节.APP应用架构、环境和敏捷开发模型介绍

文章目录 前言一、APP应用架构二、APP项目环境 2.1 后端项目环境 2.2 前端项目环境三、Scrum敏捷开发模型 3.1 Scrum敏捷模型基础介绍 3.2 Scrum敏捷开发开发流程总结 前言 一、APP应用架构 &#xff08;1&#xff09;APP应用架构 &#xff08;2&#xff0…

C++240618

1> 思维导图 2> 完善对话框&#xff0c;点击登录对话框&#xff0c; 如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出**提示”登录成功“** &#xff0c;提供一个 **OK按钮**&#xff0c;用户点击**OK后**&#xff0c;**关闭登录界面**&#xff0c; 跳转…

Canonical Juju 的一个奇怪编排部署

一周前的一个项目扩容出现了异常&#xff0c;进行了操作回滚&#xff0c;未对线上业务造成损失。 现象是这样的&#xff1a; 通过基于 Canonical Juju-GUI 在一组节点上部署了某个组件&#xff0c;在把这组节点添加到集群后&#xff0c;有4个节点上出现了同一组件的2个instanc…

Postman文件数据导入导出

前言 不同的接口测试工具如Postman、Apipost、Apifox创建的接口文档都是互通的&#xff0c;都可以互相兼容使用。我们就不需要在3个不同测试工具都去创建&#xff0c;只要在一个工具上创建&#xff0c;想要在其他接口测试工具上使用就运用导入和导出功能即可。 Postman、Apip…

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

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

【接口自动化测试】第二节.Requests库和接口对象封装

文章目录 前言一、Requests库 1.1 Requests介绍 1.2 Requests发送请求 1.3 Requests查看响应 1.4 案例1登录接口调试-获取验证码 1.5 案例2登录接口调试-登录 1.6 归纳小结二、接口对象封装 2.1 当前代码待优化问题 2.2 接口对象封装思…

互联网应用主流框架整合之SpingMVC运转逻辑及高级应用

Spring MVC处理器的执行过程 在SpringMVC的流程中&#xff0c;它会把控制器的方法封装为处理器(Handler)&#xff0c;为了更加灵活&#xff0c;SpringMVC还提供了处理器的拦截器&#xff0c;从而形成了一条包括处理器和拦截器的执行链&#xff0c;即HandlerExecutionChain&…

Linux-安装及管理程序

目录 一、Linux应用程序基础 1、应用程序与系统命令的关系 2、 典型应用程序的目录结构 3、常见的软件包封装类型 二、RPM包管理工具 1、RPM包管理器 2、RPM软件包 ​3、RPM的命令格式 4、RPM命令的常用选项 5、RPM安装 三、 yum安装 1、yum源介绍 1.1、本地yum源 …

给日期加上15天

// 给当前日期加上15天 function toAndTimeFifteen(params) {let startDate new Date(params); // 创建一个Date对象表示2024年5月31日startDate.setDate(startDate.getDate() 15); // 给当前日期加上15天let dateString formatDate(startDate)// 转换时间格式return dateSt…

自动水位雨量站:用于水库防汛预警

TH-SW2自动水位雨量站是一种现代化的监测设备&#xff0c;主要用于水库等水域的防汛预警系统。它通过集成水位和雨量监测功能&#xff0c;为水库的管理和调度提供实时、准确的数据支持。 工作原理&#xff1a; 自动水位雨量站通过内置的水位计和雨量计实时监测水库的水位变化和…

C++封装TCP类,包括客户端和服务器

头文件 XTcp.h #ifndef XTCP_H #define XTCP_H#ifdef WIN32 #ifdef XSOCKET_EXPORTS #define XSOCKET_API __declspec(dllexport) #else #define XSOCKET_API __declspec(dllimport) #endif #else #define XSOCKET_API #endif#include <string> XSOCKET_API std::string…

宁德时代华北首座电池工厂在北京开工

6月18日&#xff0c;由宁德时代与北汽集团、京能集团、小米集团等共同投资建设的北京时代电池基地项目开工仪式在北京举行。 北京市相关政府代表&#xff0c;宁德时代董事长兼CEO曾毓群&#xff0c;北汽集团董事长张建勇&#xff0c;京能集团副总经理张凤阳&#xff0c;小米集…

第6章 设备驱动程序(4)

目录 6.5 块设备操作 6.5.5 请求结构 6.5.6 BIO 6.5.7 提交请求 6.5.8 I/O调度 6.5.9 ioctl实现 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;查看后续文章。 6.5 块设备操作 6.5.5 请求结构 struct request { //放在请求队列上&#xff0…