summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin/quuid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/plugin/quuid.cpp')
-rw-r--r--src/corelib/plugin/quuid.cpp58
1 files changed, 35 insertions, 23 deletions
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 8541c7d..9332bbc 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