Qt 中实现异步散列器

news2024/11/16 3:35:46

【写在前面】

        在很多工作中,我们需要计算数据或者文件的散列值,例如登录或下载文件。

        而在 Qt 中,负责这项工作的类为 QCryptographicHash

        关于 QCryptographicHash

        QCryptographicHash 是 Qt 框架中提供的一个用于生成加密散列(哈希值)的类。该类可以将任意长度的输入(二进制或文本数据)转换成固定长度的输出(哈希值),这一过程是不可逆的。QCryptographicHash 支持多种哈希算法,包括 MD4MD5SHA-1SHA-224SHA-256SHA-384SHA-512 等,这些算法在数据完整性校验、密码存储、数字签名等应用场景中非常有用。

主要特点:

  1. 支持多种哈希算法:QCryptographicHash 提供了多种哈希算法的支持,允许开发者根据具体需求选择合适的算法。
  2. 简单易用的接口:QCryptographicHash 提供了简单易用的接口来计算哈希值。开发者可以通过调用 QCryptographicHash::hash() 静态方法或创建 QCryptographicHash 对象并使用 addData() result() 方法来计算哈希值。
  3. 逐块计算:QCryptographicHash 还可以逐块地计算哈希值,这对于处理大文件或流式数据非常有用。
  4. 可重复使用:QCryptographicHash 对象可以多次使用。当计算完一个哈希值后,可以通过调用 reset() 方法重置对象,然后继续计算新的哈希值。

         详细可见前一篇:Qt 哈希加密之 QCryptographicHash

        然鹅, 虽然 QCryptographicHash 很优秀,但它最大的问题在于其散列值的计算是同步的( 即阻塞 ),对小数据来说并没什么影响,但对大数据来说则意味明显卡顿。

        因此,我将 QCryptographicHash 进行简单封装,扩展了实用性的同时并将计算改为异步,还增加了进度通知结束通知


【正文开始】

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

        AsyncHasher 的使用方法非常简单:

        1、包含头文件:在使用 AsyncHasher 之前,需要包含相应的头文件 #include "asynchasher.h"

        2、通过 setSource setSourceText / setSourceData setSourceObject 设置源目标。

        3、通过 void hashProgress(qint64 processed, qint64 total) 来获取进度,void finished() 通知计算结束。

        4、通过 QString hashValue() const 获取最终结果。

        例如 C++ 使用:

    AsyncHasher *hasher = new AsyncHasher;
    hasher->setSourceText("Test Text");
    QObject::connect(hasher, &AsyncHasher::finished, [hasher]{
        qDebug() << hasher->hashValue();
    });

        并且我还做了 Qml 适配,使用方法:

    AsyncHasher {
        id: textHasher
        algorithm: AsyncHasher.Md5
        onStarted: {
            startTime = Date.now();
        }
        onFinished: {
            totalTime = Date.now() - startTime;
            console.log("HashValue:", hashValue, "time:", totalTime);
        }
        property real startTime: 0
        property real totalTime: 0
    }

        完整头文件如下:

#ifndef ASYNCHASHER_H
#define ASYNCHASHER_H

#include <QCryptographicHash>
#include <QFuture>
#include <QObject>
#include <QUrl>

QT_FORWARD_DECLARE_CLASS(QNetworkAccessManager);

QT_FORWARD_DECLARE_CLASS(AsyncHasherPrivate);

class AsyncHasher : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QCryptographicHash::Algorithm algorithm READ algorithm WRITE setAlgorithm NOTIFY algorithmChanged)
    Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
    Q_PROPERTY(QString hashValue READ hashValue NOTIFY hashValueChanged)
    Q_PROPERTY(int hashLength READ hashLength NOTIFY hashLengthChanged)
    Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
    Q_PROPERTY(QString sourceText READ sourceText WRITE setSourceText NOTIFY sourceTextChanged)
    Q_PROPERTY(QByteArray sourceData READ sourceData WRITE setSourceData NOTIFY sourceDataChanged)
    Q_PROPERTY(QObject* sourceObject READ sourceObject WRITE setSourceObject NOTIFY sourceObjectChanged)

public:
    Q_ENUMS(QCryptographicHash::Algorithm);

    explicit AsyncHasher(QObject *parent = nullptr);
    ~AsyncHasher();

    QNetworkAccessManager *networkManager() const;

    QCryptographicHash::Algorithm algorithm();
    void setAlgorithm(QCryptographicHash::Algorithm algorithm);

    bool asynchronous() const;
    void setAsynchronous(bool async);

    QString hashValue() const;

    int hashLength() const;

    QUrl source() const;
    void setSource(const QUrl &source);

    QString sourceText() const;
    void setSourceText(const QString &sourceText);

    QByteArray sourceData() const;
    void setSourceData(const QByteArray &sourceData);

    QObject *sourceObject() const;
    void setSourceObject(QObject *sourceObject);

    bool operator==(const AsyncHasher &hasher);
    bool operator!=(const AsyncHasher &hasher);

    QFuture<QByteArray> static hash(const QByteArray &data, QCryptographicHash::Algorithm algorithm);

signals:
    void algorithmChanged();
    void asynchronousChanged();
    void hashValueChanged();
    void hashLengthChanged();
    void sourceChanged();
    void sourceTextChanged();
    void sourceDataChanged();
    void sourceObjectChanged();
    void hashProgress(qint64 processed, qint64 total);
    void started();
    void finished();

private slots:
    void setHashValue(const QString &value);

private:
    Q_DECLARE_PRIVATE(AsyncHasher);
    QScopedPointer<AsyncHasherPrivate> d_ptr;
};

#endif // ASYNCHASHER_H

【结语】

        最后:项目链接(多多star呀..⭐_⭐):

        Github 地址:
https://github.com/mengps/QmlControls/tree/master/AsyncHashericon-default.png?t=N7T8https://github.com/mengps/QmlControls/tree/master/AsyncHasher        CSDN 的:

https://download.csdn.net/download/u011283226/89632632icon-default.png?t=N7T8https://download.csdn.net/download/u011283226/89632632

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033843.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【系统维护】Dll文件修复工具使用教程,Windows系统必备!

一、dll文件是什么 dll文件是是一种Windows操作系统下的可执行文件格式&#xff0c;包含可由多个程序同时使用的代码和数据的文件&#xff0c;它的主要作用是实现代码和数据的共享&#xff0c;从而节省内存和硬盘空间&#xff0c;并提高程序的性能和可维护性 二、如何解决dll文…

刚刚,模糊测试平台SFuzz受到行业认可

近日&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;正式发布了“2024年网络安全优秀创新成果大赛-安全严选专题赛”评选结果&#xff0c;开源网安模糊测试平台SFuzz凭借重大创新能力&#xff0c;得到组委会认可&#xff0c;获本次大赛创新产品优胜奖。 2024年网…

【LeetCode面试150】——392判断子序列

博客昵称&#xff1a;沈小农学编程 作者简介&#xff1a;一名在读硕士&#xff0c;定期更新相关算法面试题&#xff0c;欢迎关注小弟&#xff01; PS&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟沈小农&#xff0c;希望我的文章能帮助到你。欢迎大家在…

数据结构--第八天

--哈希表 -哈希表的概念 哈希表&#xff1a;用散列法存储的线性表被称为哈希表&#xff0c;使用的函数被称为散列函数或者哈希函数&#xff0c;f(k)被称为散列地址或者哈希地址。。通常情况下&#xff0c;散列表的储存空间是一个一维数组&#xff0c;而哈希地址为数组的下标 -哈…

【C# WPF】Style全局样式和资源字典

1.全局样式&#xff1a; 在Window.Resource中声明一个样式&#xff0c;总体为白色&#xff0c;为了更有区分度&#xff0c;采用BasedOn这一继承方式来在保留字体和边缘设置的基础上&#xff0c;更改颜色。 <Window x:Class"WpfApp1.Window1"xmlns"http://s…

LangChain 推出 LangGraph Studio:首款用于可视化、交互和调试复杂代理应用的代理 IDE

嘿&#xff0c;听说了吗&#xff1f;Langchain最近发布了一项重大更新&#xff0c;他们推出了官方Agent IDE&#xff0c;并且免费开放了LangGraph平台。这对于AI开发者来说是个好消息&#xff0c;意味着我们现在有了更强大的工具来构建智能应用。 今天&#xff0c;我们就来分享…

CI/CD——CI持续集成实验

目录 一. 安装Docker 二. 部署Jenkins 三. 配置邮箱 四. Harbor部署 五. Nexus Repository部署 五. sonarqube安装 六. 配置Docker 七. jenkins系统配置sonarqube 八. 配置pipeline 九. 构建并集成 一. 安装Docker docker-ce镜像_docker-ce下载地址_docker-ce安装教程…

HTTP、HTTPS、SOCKS5 三种协议特点详解

一、引言 在当今数字化的世界中&#xff0c;网络通信协议扮演着至关重要的角色。HTTP、HTTPS 和 SOCKS5 是三种常见的网络协议&#xff0c;它们各自具有独特的特点和应用场景。本文将对这三种协议进行详细的分析和比较&#xff0c;帮助您更好地理解它们在网络通信中的作用。 …

vue2+OpenLayers 天地图上打点并且显示相关的信息(2)

上次是在地图上打点 这次鼠标移动在图标上面显示相关的信息 首先有两个事件 鼠标移入 和 鼠标移出事件 pointermove pointerout 鼠标放上去之前 放上去后 代码如下 <template><div class"container"><div id"vue-openlayers" class&quo…

多模态大语言模型(MMLLM)的现状、发展和潜力

1、大模型 随着ChatGPT流行&#xff0c;大模型技术正逐渐成为AI领域的热点。许多行业大佬纷纷投身于这一赛道&#xff0c;展示了大模型的独特魅力和广阔前景。 王慧文&#xff0c;前美团联合创始人&#xff0c;发起“AI英雄帖”。 李志飞&#xff0c;出门问问创始人&#xff0…

7个Agent组成的公司,7分钟完成了一个游戏的开发

来源丨投资实习所&#xff08;ID&#xff1a;startupboy&#xff09; 作者丨StartupBoy 市场对 AI Agent 的期望一直很高&#xff0c;除了各种单向任务的 Agent 外&#xff0c;之前斯坦福大学和 Google 的一项实验已经展示了由 25 个 AI Agent 自行协同运行的虚拟城镇&#x…

如何使用Zoom API创建一个会议?

一、注册一个免费的Zoom账号&#xff08;zoom.us) 二、在Zoom 应用市场&#xff08;App Marketplace)创建一个server to server 的app&#xff0c;授予创建会议的权限。 三、创建一个Zoom API的服务端程序(node.js) 1、git clone https://github.com/zoom/server-to-server-o…

Unity新输入系统 之 InputActions(输入配置文件)

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​ 首先你应该了解新输入系统的基本单位Unity新输入系统 之 InputAction&#xff08;输入配置文件最基本的单位&#xff0…

Python-调用pymysql库,执行插入语句

今天写了一个mysql的插入方法&#xff0c;传多条数据时报错: TypeError: not enough arguments for format string 解决:后来排查是因为调用方法是&#xff0c;用的cursor.excute()&#xff0c;导致的报错&#xff0c;改为cursor.excutemany()就插入成功了 方法调用: test.ins…

【ARM CoreLink 系列 5.5 -- CI-700 Debug trace and PMU 】

文章目录 Debug trace and PMUCI-700 Debug trace 系统概述DTC DomainDTC Domain 约束条件DTM device portsDTM FIFO BufferDTM FIFO 缓冲区特点Debug trace and PMU 本篇文章主要是介绍 CI-700中实现的 Debug Trace (DT) and Performance Monitoring Unit (PMU). CI-700 Deb…

漏洞复现-Viessmann Vitogate 远程命令执行漏洞(CVE-2023-45852)

1.漏洞描述 Viessmann Vitogate是Viessmann公司的一个智能化控制系统。 Vitogate 300 2.1.3.0版本的/cgi-bin/vitogate.cgi存在一个未经身份验证的攻击者可利用的漏洞&#xff0c;通过put方法中的ipaddr params JSON数据中的shell元字符实现绕过身份验证并执行任意命令。 2.…

c++_1

C 定义头文件 #ifndef __COMPLEX__ // 这样定义头文件&#xff0c;可以解决有些cpp在包含头文件需要的次序要求&#xff1b;也不会有重复的定义头文件 #define __COMPLEX__#endif#pragma once 是 C 预处理器指令&#xff0c;用于防止头文件被多次包含&#xff0c;从而避免头文…

C++解析和构建json(cjson使用手册)

C解析和构建json【cjson使用手册】 一、cjson下载二、cjson工程使用2.1 静态库使用2.1 源码使用&#xff08;推荐&#xff09; 三、cjson详解3.1 解析json字符串3.1.1 解析对象3.1.2 解析数组&#xff1a;方法一&#xff08;获取列表数量然后按照位置获取&#xff09;3.1.2 解析…

从专家角度看:2024年值得关注的项目文档工具

国内外主流的10款项目文档管理软件对比&#xff1a;PingCode、Worktile、禅道、Tower、飞书、Smartsheet、Jira、Notion、Wrike、Basecamp。 在项目管理的世界里&#xff0c;选择一个合适的文档管理工具可能就是成功与否的关键。众多的系统和功能看似琳琅满目&#xff0c;但这也…

无字母数字绕过正则表达式

目录 1、题目代码 1.异或 php部分&#xff1a; python代码&#xff1a; 2.或 php代码 python代码 测试结果&#xff1a; 3、取反 php脚本&#xff1a; 测试结果&#xff1a; 1、题目代码 <?php error_reporting(0); highlight_file(__FILE__); $code$_GET[code…