Qt项目实战三:MD5工具开发

MD介绍

MD5消息摘要算法(英语:MD5 Message­Digest Algorithm),一种被广泛使用 的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于 确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。

MD5应用编辑

  • 一致性验证
  • 数字签名
  • 安全访问认证

需求描述

使用 notepad++ ­>工具­> MD5时,对大文件解析界面直接卡死

解决办法:处理线程和界面线程分离

界面线程直接调用肯定是不行的,因为主线程调用的工作还是在界面线程里头,还是会卡界面。需要分离线程,通过信号与槽发出去,在线程中跑起来

类 Widget

  1. 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
  1. 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

  1. 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

  1. 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;
        }
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

√沫影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值