[Writing in front]
In many jobs, we need to calculate the hash value of data or files, such as logging in or downloading files.
In Qt, the classes responsible for this areQCryptographicHash
。
with respect toQCryptographicHash
:
QCryptographicHash is a class provided in the Qt framework for generating cryptographic hashes (hashes). The class converts inputs of arbitrary length (binary or text data) into outputs of fixed length (hashes), a process that is irreversible.
QCryptographicHash
Multiple hash algorithms are supported, includingMD4, MD5, SHA-1, SHA-224, SHA-256, SHA-384 sum SHA-512
etc., these algorithms are very useful in application scenarios such as data integrity verification, cryptographic storage, and digital signatures.Key Features:
- Multiple hash algorithms are supported:
QCryptographicHash
Provides support for a variety of hash algorithms, allowing developers to choose the appropriate algorithm for their specific needs.- Easy-to-use interface:
QCryptographicHash
Provides easy-to-use interface to calculate hashes. Developers can calculate the hash value by calling theQCryptographicHash::hash()
Static methods or createQCryptographicHash
object and use theaddData()
cap (a poem)result()
method to compute the hash.- Chunk-by-chunk: `QCryptographicHash also calculates hashes chunk-by-chunk, which is useful for working with large files or streaming data.
- Reusable:
QCryptographicHash
Objects can be used multiple times. When a hash has been calculated, it can be used multiple times by calling thereset()
method resets the object and then proceeds to compute a new hash value.
But then, althoughQCryptographicHash
It's excellent, but its biggest problem is that its hash calculation is synchronized (i.e., blocking), which doesn't matter much for small data, but implies noticeable lag for big data.
Therefore, I willQCryptographicHash
Simple encapsulation to extend the utility and change the computation to asynchronous, and add progress notification and end notification.
[Text Begins]
Let's take a look.AsyncHasher
The use of the effect diagram:
AsyncHasher
It is very simple to use:
-
Include header files: When using the
AsyncHasher
Before that, you need to include the appropriate header files#include ""
。 -
pass (a bill or inspection etc)
setSource / setSourceText / setSourceData/ setSourceObject
Set the source target. -
pass (a bill or inspection etc)
void hashProgress(qint64 processed, qint64 total)
to get the progress.void finished()
Notification of the end of the calculation. -
pass (a bill or inspection etc)
QString hashValue() const
Get the final results.
Used by C++, for example:
AsyncHasher *hasher = new AsyncHasher;
hasher->setSourceText("Test Text");
QObject::connect(hasher, &AsyncHasher::finished, [hasher]{
qDebug() << hasher->hashValue();
});
And I've also made Qml adaptations to use it:
AsyncHasher {
id: textHasher
algorithm: AsyncHasher.Md5
onStarted: {
startTime = ();
}
onFinished: {
totalTime = () - startTime;
("HashValue:", hashValue, "time:", totalTime);
}
property real startTime: 0
property real totalTime: 0
}
The full header file is below:
#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
[Conclusion]
And finally: project link (more star yah...). ⭐_⭐):
Github Address:/mengps/QmlControls/tree/master/AsyncHasher