Qt 中实现异步散列器

打印 上一主题 下一主题

主题 904|帖子 904|积分 2712

【写在前面】

在很多工作中,我们需要计算数据或者文件的散列值,例如登录或下载文件。
而在 Qt 中,负责这项工作的类为 QCryptographicHash。
关于 QCryptographicHash:
QCryptographicHash 是 Qt 框架中提供的一个用于生成加密散列(哈希值)的类。该类可以将任意长度的输入(二进制或文本数据)转换成固定长度的输出(哈希值),这一过程是不可逆的。QCryptographicHash 支持多种哈希算法,包括 MD4、MD5、SHA-1、SHA-224、SHA-256、SHA-384 和 SHA-512 等,这些算法在数据完整性校验、密码存储、数字签名等应用场景中非常有用。
主要特点:

  • 支持多种哈希算法:QCryptographicHash 提供了多种哈希算法的支持,允许开辟者根据具体需求选择合适的算法。
  • 简朴易用的接口:QCryptographicHash 提供了简朴易用的接口来计算哈希值。开辟者可以通过调用 QCryptographicHash::hash() 静态方法或创建 QCryptographicHash 对象并利用 addData() 和 result() 方法来计算哈希值。
  • 逐块计算:`QCryptographicHash 还可以逐块地计算哈希值,这对于处理大文件或流式数据非常有用。
  • 可重复利用:QCryptographicHash 对象可以多次利用。当计算完一个哈希值后,可以通过调用 reset() 方法重置对象,然后继承计算新的哈希值。
然鹅, 虽然 QCryptographicHash 很良好,但它最大的问题在于其散列值的计算是同步的( 即壅闭 ),对小数据来说并没什么影响,但对大数据来说则意味明显卡顿。
因此,我将 QCryptographicHash 进行简朴封装,扩展了实用性的同时并将计算改为异步,还增加了进度通知和结束通知。
【正文开始】

先来看看 AsyncHasher 的利用效果图:

AsyncHasher 的利用方法非常简朴:

  • 包含头文件:在利用 AsyncHasher 之前,需要包含相应的头文件 #include "asynchasher.h"。
  • 通过 setSource / setSourceText / setSourceData/ setSourceObject 设置源目标。
  • 通过 void hashProgress(qint64 processed, qint64 total) 来获取进度,void finished() 通知计算结束。
  • 通过 QString hashValue() const 获取最闭幕果。
例如 C++ 利用:
  1.     AsyncHasher *hasher = new AsyncHasher;
  2.     hasher->setSourceText("Test Text");
  3.     QObject::connect(hasher, &AsyncHasher::finished, [hasher]{
  4.         qDebug() << hasher->hashValue();
  5.     });
复制代码
并且我还做了 Qml 适配,利用方法:
  1.     AsyncHasher {
  2.         id: textHasher
  3.         algorithm: AsyncHasher.Md5
  4.         onStarted: {
  5.             startTime = Date.now();
  6.         }
  7.         onFinished: {
  8.             totalTime = Date.now() - startTime;
  9.             console.log("HashValue:", hashValue, "time:", totalTime);
  10.         }
  11.         property real startTime: 0
  12.         property real totalTime: 0
  13.     }
复制代码
完整头文件如下:
  1. #ifndef ASYNCHASHER_H
  2. #define ASYNCHASHER_H
  3. #include <QCryptographicHash>
  4. #include <QFuture>
  5. #include <QObject>
  6. #include <QUrl>
  7. QT_FORWARD_DECLARE_CLASS(QNetworkAccessManager);
  8. QT_FORWARD_DECLARE_CLASS(AsyncHasherPrivate);
  9. class AsyncHasher : public QObject
  10. {
  11.     Q_OBJECT
  12.     Q_PROPERTY(QCryptographicHash::Algorithm algorithm READ algorithm WRITE setAlgorithm NOTIFY algorithmChanged)
  13.     Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
  14.     Q_PROPERTY(QString hashValue READ hashValue NOTIFY hashValueChanged)
  15.     Q_PROPERTY(int hashLength READ hashLength NOTIFY hashLengthChanged)
  16.     Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
  17.     Q_PROPERTY(QString sourceText READ sourceText WRITE setSourceText NOTIFY sourceTextChanged)
  18.     Q_PROPERTY(QByteArray sourceData READ sourceData WRITE setSourceData NOTIFY sourceDataChanged)
  19.     Q_PROPERTY(QObject* sourceObject READ sourceObject WRITE setSourceObject NOTIFY sourceObjectChanged)
  20. public:
  21.     Q_ENUMS(QCryptographicHash::Algorithm);
  22.     explicit AsyncHasher(QObject *parent = nullptr);
  23.     ~AsyncHasher();
  24.     QNetworkAccessManager *networkManager() const;
  25.     QCryptographicHash::Algorithm algorithm();
  26.     void setAlgorithm(QCryptographicHash::Algorithm algorithm);
  27.     bool asynchronous() const;
  28.     void setAsynchronous(bool async);
  29.     QString hashValue() const;
  30.     int hashLength() const;
  31.     QUrl source() const;
  32.     void setSource(const QUrl &source);
  33.     QString sourceText() const;
  34.     void setSourceText(const QString &sourceText);
  35.     QByteArray sourceData() const;
  36.     void setSourceData(const QByteArray &sourceData);
  37.     QObject *sourceObject() const;
  38.     void setSourceObject(QObject *sourceObject);
  39.     bool operator==(const AsyncHasher &hasher);
  40.     bool operator!=(const AsyncHasher &hasher);
  41.     QFuture<QByteArray> static hash(const QByteArray &data, QCryptographicHash::Algorithm algorithm);
  42. signals:
  43.     void algorithmChanged();
  44.     void asynchronousChanged();
  45.     void hashValueChanged();
  46.     void hashLengthChanged();
  47.     void sourceChanged();
  48.     void sourceTextChanged();
  49.     void sourceDataChanged();
  50.     void sourceObjectChanged();
  51.     void hashProgress(qint64 processed, qint64 total);
  52.     void started();
  53.     void finished();
  54. private slots:
  55.     void setHashValue(const QString &value);
  56. private:
  57.     Q_DECLARE_PRIVATE(AsyncHasher);
  58.     QScopedPointer<AsyncHasherPrivate> d_ptr;
  59. };
  60. #endif // ASYNCHASHER_H
复制代码
【结语】

末了:项目链接(多多star呀..⭐_⭐):
Github 地址:https://github.com/mengps/QmlControls/tree/master/AsyncHasher

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表