前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt多线程编程实战:MD5单项加密

Qt多线程编程实战:MD5单项加密

作者头像
DeROy
修改2020-09-10 12:04:01
1.2K0
修改2020-09-10 12:04:01
举报
文章被收录于专栏:编程学习基地

在MD5正向加密之前,普及一下加密技术

现在的加密/解密技术主要有三种:对称加密,非对称加密,和单向加密,这三种加密解密技术的组合就是现在电子商务的基础,它们三个有各自最适合的领域

对称加密:指的是加密方和解密方使用的是同一个密钥

非对称加密:非对称加密方式解决了对称加密的缺陷,它的加密和解密密钥是不同的,比如对一组数字加密,我们可以用公钥对其加密,然后我们想要将其还原,就必须用私钥进行解密,公钥和私钥是配对使用的,常见的非对称加密算法有:

公钥加密 私钥解密

RSA:既可以用来加密解密,又可以用来实现用户认证

DSA:只能用来加密解密,所以使用范围没有RSA广

非对称加密长度通常有512,1024,2048,4096位,最常用的就是2048位,长度固然可以增加安全性但是需要花费很长时间来进行加密/解密,和对称加密相比,加密/解密的时间差不多是对称加密的1000倍,所以我们通常用其作为用户认证,用对称加密来实现数据的加密/解密

ps:加密长度512位可以暴力破解

单项加密:单向加密就是用来计算一段数据的特征码的,为了防止用户通过“暴力破解”的方式解密,所以单向加密一般具有“雪崩效应”就是说:只要被加密内容有一点点的不同,加密所得结果就会有很大的变化。单项加密还有一个特点就是无论被加密的内容多长/短,加密的结果(就是提取特征码)是定长的,用途:用于验证数据的完整性,常用的单项加密算法

MD5:这种加密算法固定长度为128位

SHA1:这种加密算法固定长度是160位

本期通过Qt QCryptographicHash::Md5 对磁盘上的文件进行单项加密

效果展示:

对2.86 GB (3,076,476,328 字节)的文件在线程中进行单项加密,不卡主界面,加密进度通过信号/槽返回给主界面显示。

QCryptographicHash加密方式

详情看官网文档,只列举少部分

代码语言:javascript
复制
enum Algorithm { Md4, Md5, Sha1, Sha224, ..., Keccak_512 }

两种处理数据的方式

少量数据的加密

代码语言:javascript
复制
QByteArray hash(const QByteArray &data, QCryptographicHash::Algorithm method)

示例:

代码语言:javascript
复制
QByteArray temp=file.readAll();	/*读取数据*/
QByteArray md5=QCryptographicHash::hash(temp,QCryptographicHash::Md5);
ui->textEdit->setText(md5.toHex());/*MD5:这种加密算法固定长度为128位,32字节*/
  • 缺陷:当文档很大时readAll会出错

大量数据的加密

代码语言:javascript
复制
void addData(const QByteArray &data)

示例:

代码语言:javascript
复制
QCryptographicHash hash(QCryptographicHash::Md5);
while(!file.atEnd())
{
 	QByteArray content = file.read(1024*1024);	/*读取1M数据*/
  	hash.addData(content);						/*多次计算*/
 }
 QByteArray md5 = hash.result().toHex();		/*MD5:这种加密算法固定长度为128位,32字节*/

Md5单项加密对象设计

signals:

代码语言:javascript
复制
signals:
    void sendMd5CheckSumSignal(QByteArray);         //反馈md5值到界面
    void sendProgressBarSignal(int, int);           //反馈进度到界面 以生成进度条

public slots:

代码语言:javascript
复制
public slots:
    void getMd5CheckSumSlot(const QString &filePath);	/*Md5单项加密计算槽函数*/

md5check.h

代码语言:javascript
复制
#ifndef MD5CHECK_H
#define MD5CHECK_H

#include <QObject>
#include <QCryptographicHash>
#include <QFile>
#include <QFileInfo>
#include <QDebug>

class Md5Check : public QObject
{
    Q_OBJECT
public:
    explicit Md5Check(QObject *parent = nullptr);

signals:
    void sendMd5CheckSumSignal(QByteArray);         //反馈md5值到界面
    void sendProgressBarSignal(int, int);           //反馈进度到界面 以生成进度条
    //已经处理的数据量 待处理的总量

public slots:
    void getMd5CheckSumSlot(const QString &filePath);
};

#endif // MD5CHECK_H

md5check.cpp

代码语言:javascript
复制
#include "md5check.h"

Md5Check::Md5Check(QObject *parent) : QObject(parent){}

void Md5Check::getMd5CheckSumSlot(const QString &filePath)
{
    QFile file(filePath);
    QByteArray md5Result;
    QFileInfo md5FileInfo;
    md5FileInfo = QFileInfo(filePath);  /*获取文件信息,考虑到文件过大*/

    int totalSize = md5FileInfo.size()/(1024*1024); /*   把Byte字节转换成M兆    */
    if(md5FileInfo.size()%(1024*1024)>0)
        totalSize+=1;                               /*   多余补一    */
    int currentSize = 0;                /*当前进度,读取的M兆数*/

    if(file.open(QIODevice::ReadOnly))
    {
        QCryptographicHash hash(QCryptographicHash::Md5);
        while (!file.atEnd()) {         //读取文件直到读物完整
            QByteArray content = file.read(1024*1024);  /*每次读取一兆M*/
            hash.addData(content);      /*分段进程MD5累加*/
            currentSize++;              /*当前进度,进度加一*/
            emit sendProgressBarSignal(totalSize,currentSize);  /*传送百分比信号*/
        }
        md5Result = hash.result().toHex();      /*MD5值为32位的十六进制数*/
        emit sendMd5CheckSumSignal(md5Result);  /*发送MD5结果*/
        file.close();
    }
}

线程处理IO操作

定义Md5Check对象以及处理线程

代码语言:javascript
复制
QThread md5Thread;          //线程
Md5Check mMd5CheckSum;

将对象移至线程

代码语言:javascript
复制
mMd5CheckSum.moveToThread(&md5Thread);      /*从一个object 移动到 一个thread*/
md5Thread.start();                          /*开启线程*/

关联信号与槽

代码语言:javascript
复制
/* 关联MD5计算槽函数 让Md5Check对象开始计算MD5值 */
connect(this,SIGNAL(checkMd5SumSignal(QString)),&mMd5CheckSum,SLOT(getMd5CheckSumSlot(QString)));
/*关联MD5结果返回信号,将MD5计算结果传递给Widget定义的槽函数recvMd5CheckSumSlot*/
connect(&mMd5CheckSum, SIGNAL(sendMd5CheckSumSignal(QByteArray)),this, SLOT(recvMd5CheckSumSlot(QByteArray)));
/*关联MD5计算进度,将进度返回给Widget定义的槽函数recvProgressBarSlot*/
connect(&mMd5CheckSum, SIGNAL(sendProgressBarSignal(int,int)),this, SLOT(recvProgressBarSlot(int,int)));

开启md5单项加密任务

代码语言:javascript
复制
emit checkMd5SumSignal(md5Filename); /*将打开的文件路径通过信号传递给Md5Check对象*/

关键字【MD5单项加密】

End

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程学习基地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • QCryptographicHash加密方式
  • 两种处理数据的方式
    • 少量数据的加密
      • 大量数据的加密
      • Md5单项加密对象设计
        • signals:
          • public slots:
            • md5check.h
              • md5check.cpp
                • 线程处理IO操作
                  • 将对象移至线程
                    • 关联信号与槽
                      • 开启md5单项加密任务
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档