MD介绍
MD5消息摘要算法(英语:MD5 MessageDigest Algorithm),一种被广泛使用 的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于 确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。
MD5应用编辑
- 一致性验证
- 数字签名
- 安全访问认证
需求描述
使用 notepad++ >工具> MD5时,对大文件解析界面直接卡死
解决办法:处理线程和界面线程分离
界面线程直接调用肯定是不行的,因为主线程调用的工作还是在界面线程里头,还是会卡界面。需要分离线程,通过信号与槽发出去,在线程中跑起来
类 Widget
- Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFile>
#include <QFileInfo>
#include <QFileDialog>
#include <QDebug>
#include <QCryptographicHash>
#include <QThread>
#include "md5Check.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
signals:
void checkMd5SumSignal(QString filePath);
private slots:
void recvMd5CheckSunSlot(const QByteArray &);
void recvProgressBarSlot(int, int);
void on_pushButton_clicked();
void on_toolButton_2_triggered(QAction *arg1);
void on_toolButton_2_clicked();
private:
Ui::Widget *ui;
Md5Check mMd5CheckSum;
QThread Md5Thread;
};
#endif // WIDGET_H
- Widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
Md5Thread.start();
mMd5CheckSum.moveToThread(&Md5Thread);
qDebug()<< "Widget::Widget" << QThread::currentThreadId();
/* 启动转换 */
connect(&mMd5CheckSum, SIGNAL(sendMd5CheckSunSignal(QByteArray)),
this, SLOT(recvMd5CheckSunSlot(QByteArray)), Qt::QueuedConnection);
/* 反馈进度 */
connect(&mMd5CheckSum, SIGNAL(sendProgressBarSignal(int,int)),
this, SLOT(recvProgressBarSlot(int,int)));
/* 结果反馈 */
connect(this, SIGNAL(checkMd5SumSignal(QString)),
&mMd5CheckSum, SLOT(getMd5CheckSumSlot(QString)));
}
Widget::~Widget()
{
Md5Thread.terminate();
Md5Thread.wait(10000);
// Md5Thread.exit(); //线程退出
// Md5Thread.wait(10 * 1000); //10秒超时
//10秒以内,如果线程退出了,退出阻塞
delete ui;
}
void Widget::on_pushButton_clicked()
{
this->close();
}
void Widget::on_toolButton_2_triggered(QAction *arg1)
{
}
void Widget::recvMd5CheckSunSlot(const QByteArray & md5)
{
ui->textBrowser->setText(md5);
}
void Widget::recvProgressBarSlot(int current, int max)
{
ui->progressBar->setMaximum(max);
ui->progressBar->setValue(current);
}
void Widget::on_toolButton_2_clicked()
{
QString md5FileName = QFileDialog::getOpenFileName(this,
QString::fromLocal8Bit("选择需要MD5的文件"));
if(!md5FileName.isEmpty())
{
// mMd5CheckSum.getMd5CheckSumSlot(md5FileName); //直接调用 一定是在同一个线程
emit checkMd5SumSignal(md5FileName);
ui->lineEdit->setText(md5FileName);
}
}
类 Md5Check
- Md5Check.h
#ifndef MD5CHECK_H
#define MD5CHECK_H
/*
计算md5值:
反馈md5值
反馈进度:
*/
#include <QObject>
#include <QFile>
#include <QFileInfo>
#include <QFileDialog>
#include <QDebug>
#include <QCryptographicHash>
#include <QThread>
class Md5Check : public QObject
{
Q_OBJECT
public:
explicit Md5Check(QObject *parent = nullptr);
signals:
void sendMd5CheckSunSignal(const QByteArray &); //反馈md5值到界面
void sendProgressBarSignal(int, int); //反馈进度到界面 以生存进度条
public slots:
void getMd5CheckSumSlot(const QString &filePath);
};
#endif // MD5CHECK_H
- Md5Check.cpp
#include "md5Check.h"
Md5Check::Md5Check(QObject *parent) : QObject(parent)
{
}
void Md5Check::getMd5CheckSumSlot(const QString &checkFile)
{
QFileInfo md5FileInfo;
QString md5FileName = checkFile;
qDebug() << md5FileName;
QByteArray md5;
md5FileInfo = QFileInfo(md5FileName);
int fileSize = md5FileInfo.size(); //文件总大小
int haveReadSize = 0; //已经处理过了的文件的大小
int totalFileSize = int(md5FileInfo.size() / (1024 * 1024));
qDebug() << "totalFileSize" << totalFileSize <<QThread::currentThreadId();
if(md5FileInfo.exists())
{
QFile file(md5FileName);
if (!file.open(QIODevice::ReadOnly))
{
qDebug() << file.errorString();
}
else
{
qDebug() << "open sucess !";
QCryptographicHash hash(QCryptographicHash::Md5);
while(!file.atEnd())
{
QByteArray content = file.read(1024*1024); //1M 最后不足1M,把最后的读完
hash.addData(content);
haveReadSize++;
//qDebug() << "haveReadSize" << haveReadSize;
emit sendProgressBarSignal(haveReadSize, totalFileSize); //尺寸很有可能大于int32
}
//emit sendProgressBarSignal(fileSize, fileSize); //作弊
md5 = hash.result().toHex();
emit sendMd5CheckSunSignal(md5);
qDebug() << md5;
}
}
}