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