summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/plugin/quuid.cpp65
-rw-r--r--src/corelib/plugin/quuid.h22
-rw-r--r--tests/auto/corelib/plugin/quuid/tst_quuid.cpp28
-rw-r--r--tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp20
4 files changed, 129 insertions, 6 deletions
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 46589f88bc..e73508fce6 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -133,6 +133,29 @@ bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&
}
#endif
+static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCryptographicHash::Algorithm algorithm, int version)
+{
+ QByteArray hashResult;
+
+ // create a scope so later resize won't reallocate
+ {
+ QCryptographicHash hash(algorithm);
+ hash.addData(ns.toRfc4122());
+ hash.addData(baseData);
+ hashResult = hash.result();
+ }
+ hashResult.resize(16); // Sha1 will be too long
+
+ QUuid result = QUuid::fromRfc4122(hashResult);
+
+ result.data3 &= 0x0FFF;
+ result.data3 |= (version << 12);
+ result.data4[0] &= 0x3F;
+ result.data4[0] |= 0x80;
+
+ return result;
+}
+
/*!
\class QUuid
\brief The QUuid class stores a Universally Unique Identifier (UUID).
@@ -231,7 +254,7 @@ bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&
\o 0
\o 1
\o 1
- \o Name
+ \o Md5(Name)
\row
\o 0
@@ -240,6 +263,13 @@ bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&
\o 0
\o Random
+ \row
+ \o 0
+ \o 1
+ \o 0
+ \o 1
+ \o Sha1
+
\endtable
The field layouts for the DCE versions listed in the table above
@@ -385,9 +415,40 @@ QUuid::QUuid(const QByteArray &text)
return;
}
}
+
#endif
/*!
+ \since 5.0
+ \fn QUuid::createUuidV3()
+
+ This functions returns a new UUID with variant QUuid::DCE and version QUuid::MD5.
+ \a ns is the namespace and \a name is the name as described by RFC 4122.
+
+ \sa variant(), version(), createUuidV5()
+*/
+
+/*!
+ \since 5.0
+ \fn QUuid::createUuidV5()
+
+ This functions returns a new UUID with variant QUuid::DCE and version QUuid::SHA1.
+ \a ns is the namespace and \a name is the name as described by RFC 4122.
+
+ \sa variant(), version(), createUuidV3()
+*/
+
+QUuid QUuid::createUuidV3(const QUuid &ns, const QByteArray &baseData)
+{
+ return createFromName(ns, baseData, QCryptographicHash::Md5, 3);
+}
+
+QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData)
+{
+ return createFromName(ns, baseData, QCryptographicHash::Sha1, 5);
+}
+
+/*!
Creates a QUuid object from the binary representation of the UUID, as
specified by RFC 4122 section 4.1.2. See toRfc4122() for a further
explanation of the order of bytes required.
@@ -731,7 +792,7 @@ QUuid::Version QUuid::version() const
if (isNull()
|| (variant() != DCE)
|| ver < Time
- || ver > Random)
+ || ver > Sha1)
return VerUnknown;
return ver;
}
diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h
index 2eec1575e5..9efb2ba37c 100644
--- a/src/corelib/plugin/quuid.h
+++ b/src/corelib/plugin/quuid.h
@@ -43,6 +43,7 @@
#define QUUID_H
#include <QtCore/qstring.h>
+#include <QtCore/qcryptographichash.h>
QT_BEGIN_HEADER
@@ -79,8 +80,10 @@ public:
VerUnknown =-1,
Time = 1, // 0 0 0 1
EmbeddedPOSIX = 2, // 0 0 1 0
- Name = 3, // 0 0 1 1
- Random = 4 // 0 1 0 0
+ Md5 = 3, // 0 0 1 1
+ Name = Md5,
+ Random = 4, // 0 1 0 0
+ Sha1 = 5 // 0 1 0 1
};
QUuid()
@@ -173,6 +176,21 @@ public:
}
#endif
static QUuid createUuid();
+ static QUuid createUuidV3(const QUuid &ns, const QByteArray &baseData);
+ static QUuid createUuidV5(const QUuid &ns, const QByteArray &baseData);
+#ifndef QT_NO_QUUID_STRING
+ static inline QUuid createUuidV3(const QUuid &ns, const QString &baseData)
+ {
+ return QUuid::createUuidV3(ns, baseData.toUtf8());
+ }
+
+ static inline QUuid createUuidV5(const QUuid &ns, const QString &baseData)
+ {
+ return QUuid::createUuidV5(ns, baseData.toUtf8());
+ }
+
+#endif
+
QUuid::Variant variant() const;
QUuid::Version version() const;
diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
index b7c4130236..789659cd04 100644
--- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
+++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
@@ -59,6 +59,7 @@ private slots:
void fromByteArray();
void toRfc4122();
void fromRfc4122();
+ void createUuidV3OrV5();
void check_QDataStream();
void isNull();
void equal();
@@ -81,21 +82,34 @@ private slots:
public:
// Variables
+ QUuid uuidNS;
QUuid uuidA;
QUuid uuidB;
+ QUuid uuidC;
+ QUuid uuidD;
};
void tst_QUuid::initTestCase()
{
+ //It's NameSpace_DNS in RFC4122
+ //"{6ba7b810-9dad-11d1-80b4-00c04fd430c8}";
+ uuidNS = QUuid(0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8);
+
//"{fc69b59e-cc34-4436-a43c-ee95d128b8c5}";
- uuidA = QUuid(0xfc69b59e, 0xcc34 ,0x4436 ,0xa4 ,0x3c ,0xee ,0x95 ,0xd1 ,0x28 ,0xb8 ,0xc5);
+ uuidA = QUuid(0xfc69b59e, 0xcc34, 0x4436, 0xa4, 0x3c, 0xee, 0x95, 0xd1, 0x28, 0xb8, 0xc5);
//"{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}";
- uuidB = QUuid(0x1ab6e93a ,0xb1cb ,0x4a87 ,0xba ,0x47 ,0xec ,0x7e ,0x99 ,0x03 ,0x9a ,0x7b);
+ uuidB = QUuid(0x1ab6e93a, 0xb1cb, 0x4a87, 0xba, 0x47, 0xec, 0x7e, 0x99, 0x03, 0x9a, 0x7b);
// chdir to the directory containing our testdata, then refer to it with relative paths
QString testdata_dir = QFileInfo(QFINDTESTDATA("testProcessUniqueness")).absolutePath();
QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
+
+ //"{3d813cbb-47fb-32ba-91df-831e1593ac29}"; http://www.rfc-editor.org/errata_search.php?rfc=4122&eid=1352
+ uuidC = QUuid(0x3d813cbb, 0x47fb, 0x32ba, 0x91, 0xdf, 0x83, 0x1e, 0x15, 0x93, 0xac, 0x29);
+
+ //"{21f7f8de-8051-5b89-8680-0195ef798b6a}";
+ uuidD = QUuid(0x21f7f8de, 0x8051, 0x5b89, 0x86, 0x80, 0x01, 0x95, 0xef, 0x79, 0x8b, 0x6a);
}
void tst_QUuid::fromChar()
@@ -164,6 +178,16 @@ void tst_QUuid::fromRfc4122()
QCOMPARE(uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")));
}
+void tst_QUuid::createUuidV3OrV5()
+{
+ //"www.widgets.com" is also from RFC4122
+ QCOMPARE(uuidC, QUuid::createUuidV3(uuidNS, QByteArray("www.widgets.com")));
+ QCOMPARE(uuidC, QUuid::createUuidV3(uuidNS, QString("www.widgets.com")));
+
+ QCOMPARE(uuidD, QUuid::createUuidV5(uuidNS, QByteArray("www.widgets.com")));
+ QCOMPARE(uuidD, QUuid::createUuidV5(uuidNS, QString("www.widgets.com")));
+}
+
void tst_QUuid::check_QDataStream()
{
QUuid tmp;
diff --git a/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp b/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp
index 981acae99d..9e33655d18 100644
--- a/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp
+++ b/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp
@@ -60,6 +60,8 @@ private slots:
void fromByteArray();
void toRfc4122();
void fromRfc4122();
+ void createUuidV3();
+ void createUuidV5();
void toDataStream();
void fromDataStream();
void isNull();
@@ -129,6 +131,24 @@ void tst_bench_QUuid::fromRfc4122()
}
}
+void tst_bench_QUuid::createUuidV3()
+{
+ QUuid ns = QUuid::createUuid();
+ QByteArray name = QByteArray("Test");
+ QBENCHMARK {
+ QUuid uuid = QUuid::createUuidV3(ns, name);
+ }
+}
+
+void tst_bench_QUuid::createUuidV5()
+{
+ QUuid ns = QUuid::createUuid();
+ QByteArray name = QByteArray("Test");
+ QBENCHMARK {
+ QUuid uuid = QUuid::createUuidV5(ns, name);
+ }
+}
+
void tst_bench_QUuid::toDataStream()
{
QUuid uuid1, uuid2;