Add V3(md5) and V5(sha1) version for DCE in QUuid

Add the above versions based on RFC4122 standard.

Done-with: Hagen Rother
Task-number: QTBUG-23071
Change-Id: Ieb90925374d1e3c85011b899b8dd3bb1a608c561
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
Reviewed-by: Denis Dzyubenko <denis.dzyubenko@nokia.com>
This commit is contained in:
Liang Qi 2012-01-04 11:15:20 +01:00 committed by Qt by Nokia
parent 679c4c002d
commit 8c72dc5907
4 changed files with 129 additions and 6 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;