本帖最后由 zdsub 于 2023-8-13 09:42 编辑
QtFileHash
QtFileHash是一款基于Qt开发的跨平台文件校验工具,支持Windows、Linux、MacOS平台,支持MD4、MD5、SHA1、SHA256、SHA512算法。
项目地址:https://github.com/zdsub/QtFilehash
项目演示:https://www.bilibili.com/video/BV1ZM4y1x7rk
功能特点
- 基于Qt 5.15开发
- 支持Windows、Linux、MacOS平台
- 支持MD4、MD5、SHA1、SHA256、SHA512算法
- 支持计算单个或多个文件
- 支持通过拖拽,计算单个或多个文件
- 支持通过启动参数,计算单个或多个文件
- 支持分块计算和停止计算
- 支持显示计算进度
- 支持复制、导出、清除计算结果
项目截图
Windows
Linux
MacOS
核心代码
filehashthread.h
#ifndef FILEHASHTHREAD_H
#define FILEHASHTHREAD_H
#include <QThread>
#include <QCryptographicHash>
class FileHashThread : public QThread
{
Q_OBJECT
public:
// 构造函数
FileHashThread();
// 析构函数
~FileHashThread();
// 线程函数
void run() Q_DECL_OVERRIDE;
// 设置待计算文件集合
void setFileList(QStringList fileList);
// 设置是否停止计算
void setStop(bool isStop);
private:
// 计算文件哈希
void hash(QString path, int index);
// 发送错误信息
void emitError(int index, QString error);
private:
// 待计算文件集合
QStringList fileList;
// 是否停止计算
bool isStop;
// 文件缓冲区
int bufferSize;
// 校验算法
QCryptographicHash* md4;
QCryptographicHash* md5;
QCryptographicHash* sha1;
QCryptographicHash* sha256;
QCryptographicHash* sha512;
signals:
// 哈希校验开始
void hashStarted(int count);
// 哈希校验结束
void hashEnded();
// 哈希校验错误
void hashError(QString error);
// 哈希校验进度改变
void hashProgressChanged(int progress);
// 哈希校验索引改变
void hashIndexChanged(int index);
// 哈希校验结果
void hashResult(QString result);
};
#endif // FILEHASHTHREAD_H
filehashthread.cpp
#include "filehashthread.h"
#include <QFile>
#include <QFileInfo>
FileHashThread::FileHashThread()
{
isStop = false;
bufferSize = 4096;
md4 = new QCryptographicHash(QCryptographicHash::Md4);
md5 = new QCryptographicHash(QCryptographicHash::Md5);
sha1 = new QCryptographicHash(QCryptographicHash::Sha1);
sha256 = new QCryptographicHash(QCryptographicHash::Sha256);
sha512 = new QCryptographicHash(QCryptographicHash::Sha512);
}
FileHashThread::~FileHashThread()
{
delete md4;
delete md5;
delete sha1;
delete sha256;
delete sha512;
}
void FileHashThread::setFileList(QStringList fileList)
{
this->fileList = fileList;
}
void FileHashThread::setStop(bool isStop)
{
this->isStop = isStop;
}
void FileHashThread::run()
{
int size = fileList.size();
if (size > 0)
{
emit hashStarted(size);
for (int i = 0; i < size && !isStop; i++)
hash(fileList[i], i);
emit hashEnded();
}
}
void FileHashThread::hash(QString filePath, int index) {
QFileInfo info(filePath);
if (!info.exists())
{
emitError(index, "文件不存在");
return;
}
else if (!info.isFile())
{
emitError(index, "不是文件");
return;
}
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly))
{
emitError(index, "打开文件失败");
return;
}
long long size = 0;
long long fileSize = file.size();
if (fileSize != 0)
{
while (size < fileSize && !isStop)
{
QByteArray byteArray = file.read(bufferSize);
md4->addData(byteArray);
md5->addData(byteArray);
sha1->addData(byteArray);
sha256->addData(byteArray);
sha512->addData(byteArray);
size += byteArray.size();
emit hashProgressChanged(static_cast<double>(size) / fileSize * 100);
}
}
else
emit hashProgressChanged(100);
file.close();
// 完成计算
if (size == fileSize)
{
// 获取校验结果
QString _md4 = md4->result().toHex().toUpper();
QString _md5 = md5->result().toHex().toUpper();
QString _sha1 = sha1->result().toHex().toUpper();
QString _sha256 = sha256->result().toHex().toUpper();
QString _sha512 = sha512->result().toHex().toUpper();
// 格式化校验结果
QString message = "文件: %1\n"
"大小: %2字节\n"
"MD4: %3\n"
"MD5: %4\n"
"SHA1: %5\n"
"SHA256: %6\n"
"SHA512: %7\n";
QString result = message.arg(filePath, QString::number(fileSize), _md4, _md5, _sha1, _sha256, _sha512);
emit hashResult(result);
emit hashIndexChanged(index + 1);
}
// 重置检验结果
md4->reset();
md5->reset();
sha1->reset();
sha256->reset();
sha512->reset();
}
void FileHashThread::emitError(int index, QString error)
{
emit hashError(fileList[index] + "\n" + error + "\n");
emit hashProgressChanged(100);
emit hashIndexChanged(index + 1);
}
|