From 8c72dc5907a97fce718f6810d446ecf6ea41b588 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 4 Jan 2012 11:15:20 +0100 Subject: Add V3(md5) and V5(sha1) version for DCE in QUuid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the above versions based on RFC4122 standard. Done-with: Hagen Rother Task-number: QTBUG-23071 Change-Id: Ieb90925374d1e3c85011b899b8dd3bb1a608c561 Reviewed-by: João Abecasis Reviewed-by: Denis Dzyubenko --- src/corelib/plugin/quuid.cpp | 65 +++++++++++++++++++++- src/corelib/plugin/quuid.h | 22 +++++++- tests/auto/corelib/plugin/quuid/tst_quuid.cpp | 28 +++++++++- .../benchmarks/corelib/plugin/quuid/tst_quuid.cpp | 20 +++++++ 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,8 +415,39 @@ 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 @@ -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 +#include 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; -- cgit v1.2.3