diff options
author | Darin Broady <dbroady1@yahoo.com> | 2010-06-21 11:41:04 +0200 |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-06-21 11:41:04 +0200 |
commit | 4363d4eebce4afd2ce3b3d6da205f8037357099a (patch) | |
tree | b36ef3486c9fb63af073686ccac3b7c92ef33487 /src/corelib/plugin/quuid.cpp | |
parent | b000d828d20793b2aad0e9d1449adaf1331c0b01 (diff) | |
download | qt4-tools-4363d4eebce4afd2ce3b3d6da205f8037357099a.tar.gz |
Allow Unix to generate unique UUIDs if /dev/urandom exists.
Merge-request: 629
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Diffstat (limited to 'src/corelib/plugin/quuid.cpp')
-rw-r--r-- | src/corelib/plugin/quuid.cpp | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 8541c7db5b..9332bbcf7c 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -546,13 +546,13 @@ bool QUuid::operator>(const QUuid &other) const \fn QUuid QUuid::createUuid() On any platform other than Windows, this function returns a new - UUID with variant QUuid::DCE and version QUuid::Random. The random - numbers used to construct the UUID are obtained from the local - pseudo-random generator, qrand(), which is usually not a cryptographic - quality random number generator. Therefore, a UUID generated by - this function can't be guaranteed to be unique. If the pseudo-random - number generator for the calling thread has not yet been seeded, this - function will seed the pseudo-random number generator by calling qsrand(). + UUID with variant QUuid::DCE and version QUuid::Random. If + the /dev/urandom device exists, then the numbers used to construct + the UUID will be of cryptographic quality, which will make the UUID + unique. Otherwise, the numbers of the UUID will be obtained from + the local pseudo-random number generator (qrand(), which is seeded + by qsrand()) which is usually not of cryptograhic quality, which + means that the UUID can't be guaranteed to be unique. On a Windows platform, a GUID is generated, which almost certainly \e{will} be unique, on this or any other system, networked or not. @@ -577,6 +577,7 @@ QUuid QUuid::createUuid() QT_BEGIN_INCLUDE_NAMESPACE #include "qdatetime.h" +#include "qfile.h" #include "stdlib.h" // For srand/rand QT_END_INCLUDE_NAMESPACE @@ -584,24 +585,35 @@ extern void qsrand(); // in qglobal.cpp QUuid QUuid::createUuid() { - static const int intbits = sizeof(int)*8; - static int randbits = 0; - if (!randbits) { - int max = RAND_MAX; - do { ++randbits; } while ((max=max>>1)); - } - - // reseed, but only if not already seeded - qsrand(); - QUuid result; uint *data = &(result.data1); - int chunks = 16 / sizeof(uint); - while (chunks--) { - uint randNumber = 0; - for (int filled = 0; filled < intbits; filled += randbits) - randNumber |= qrand()<<filled; - *(data+chunks) = randNumber; + +#ifdef Q_OS_UNIX + QFile devUrandom; + devUrandom.setFileName(QLatin1String("/dev/urandom")); + if (devUrandom.open(QIODevice::ReadOnly)) { + qint64 numToRead = 4 * sizeof(uint); + devUrandom.read((char *) data, numToRead); // should read 128-bits of data + } else +#endif + { + static const int intbits = sizeof(int)*8; + static int randbits = 0; + if (!randbits) { + int max = RAND_MAX; + do { ++randbits; } while ((max=max>>1)); + } + + // reseed, but only if not already seeded + qsrand(); + + int chunks = 16 / sizeof(uint); + while (chunks--) { + uint randNumber = 0; + for (int filled = 0; filled < intbits; filled += randbits) + randNumber |= qrand()<<filled; + *(data+chunks) = randNumber; + } } result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE |