一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

MD介绍

  MD5消息摘要算法(英语:MD5 Message­Digest 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 }

 

posted on 2024-02-19 13:50  一杯清酒邀明月  阅读(105)  评论(0编辑  收藏  举报