1// Copyright (C) 2021 Intel Corporation.
2// Copyright (C) 2021 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5// for rand_s
6#define _CRT_RAND_S
7
8#include "qrandom.h"
9#include "qrandom_p.h"
10#include <qendian.h>
11#include <qmutex.h>
12#include <qobjectdefs.h>
13
14#include <errno.h>
15
16#if QT_CONFIG(getauxval)
17# include <sys/auxv.h>
18#endif
19
20#if QT_CONFIG(getentropy) && __has_include(<sys/random.h>)
21# include <sys/random.h>
22#elif !QT_CONFIG(getentropy) && (!defined(Q_OS_BSD4) || defined(__GLIBC__)) && !defined(Q_OS_WIN)
23# include "qdeadlinetimer.h"
24# include "qhashfunctions.h"
25#endif // !QT_CONFIG(getentropy)
26
27#ifdef Q_OS_UNIX
28# include <fcntl.h>
29# include <private/qcore_unix_p.h>
30#else
31# include <qt_windows.h>
32
33// RtlGenRandom is not exported by its name in advapi32.dll, but as SystemFunction036
34// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694(v=vs.85).aspx
35// Implementation inspired on https://hg.mozilla.org/mozilla-central/file/722fdbff1efc/security/nss/lib/freebl/win_rand.c#l146
36// Argument why this is safe to use: https://bugzilla.mozilla.org/show_bug.cgi?id=504270
37extern "C" {
38DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength);
39}
40#endif
41
42// This file is too low-level for regular Q_ASSERT (the logging framework may
43// recurse back), so use regular assert()
44#undef NDEBUG
45#undef Q_ASSERT_X
46#undef Q_ASSERT
47#define Q_ASSERT(cond) assert(cond)
48#define Q_ASSERT_X(cond, x, msg) assert(cond && msg)
49#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
50# define NDEBUG 1
51#endif
52#include <assert.h>
53
54QT_BEGIN_NAMESPACE
55
56enum {
57 // may be "overridden" by a member enum
58 FillBufferNoexcept = true
59};
60
61#if defined(QT_BUILD_INTERNAL)
62QBasicAtomicInteger<uint> qt_randomdevice_control = Q_BASIC_ATOMIC_INITIALIZER(0U);
63#endif
64
65struct QRandomGenerator::SystemGenerator
66{
67#if QT_CONFIG(getentropy)
68 static qsizetype fillBuffer(void *buffer, qsizetype count) noexcept
69 {
70 // getentropy can read at most 256 bytes, so break the reading
71 qsizetype read = 0;
72 while (count - read > 256) {
73 // getentropy can't fail under normal circumstances
74 int ret = getentropy(buffer: reinterpret_cast<uchar *>(buffer) + read, length: 256);
75 Q_ASSERT(ret == 0);
76 Q_UNUSED(ret);
77 read += 256;
78 }
79
80 int ret = getentropy(buffer: reinterpret_cast<uchar *>(buffer) + read, length: count - read);
81 Q_ASSERT(ret == 0);
82 Q_UNUSED(ret);
83 return count;
84 }
85
86#elif defined(Q_OS_UNIX)
87 enum { FillBufferNoexcept = false };
88
89 QBasicAtomicInt fdp1; // "file descriptor plus 1"
90 int openDevice()
91 {
92 int fd = fdp1.loadAcquire() - 1;
93 if (fd != -1)
94 return fd;
95
96 fd = qt_safe_open("/dev/urandom", O_RDONLY);
97 if (fd == -1)
98 fd = qt_safe_open("/dev/random", O_RDONLY | O_NONBLOCK);
99 if (fd == -1) {
100 // failed on both, set to -2 so we won't try again
101 fd = -2;
102 }
103
104 int opened_fdp1;
105 if (fdp1.testAndSetOrdered(0, fd + 1, opened_fdp1))
106 return fd;
107
108 // failed, another thread has opened the file descriptor
109 if (fd >= 0)
110 qt_safe_close(fd);
111 return opened_fdp1 - 1;
112 }
113
114#ifdef Q_CC_GNU
115 // If it's not GCC or GCC-like, then we'll leak the file descriptor
116 __attribute__((destructor))
117#endif
118 static void closeDevice()
119 {
120 int fd = self().fdp1.loadRelaxed() - 1;
121 if (fd >= 0)
122 qt_safe_close(fd);
123 }
124
125 constexpr SystemGenerator() : fdp1 Q_BASIC_ATOMIC_INITIALIZER(0) {}
126
127 qsizetype fillBuffer(void *buffer, qsizetype count)
128 {
129 int fd = openDevice();
130 if (Q_UNLIKELY(fd < 0))
131 return 0;
132
133 qint64 n = qt_safe_read(fd, buffer, count);
134 return qMax<qsizetype>(n, 0); // ignore any errors
135 }
136
137#elif defined(Q_OS_WIN)
138 static qsizetype fillBuffer(void *buffer, qsizetype count) noexcept
139 {
140 auto RtlGenRandom = SystemFunction036;
141 return RtlGenRandom(buffer, ULONG(count)) ? count: 0;
142 }
143#endif // Q_OS_WIN
144
145 static SystemGenerator &self();
146 typedef quint32 result_type;
147 void generate(quint32 *begin, quint32 *end) noexcept(FillBufferNoexcept);
148
149 // For std::mersenne_twister_engine implementations that use something
150 // other than quint32 (unsigned int) to fill their buffers.
151 template<typename T>
152 void generate(T *begin, T *end)
153 {
154 static_assert(sizeof(T) >= sizeof(quint32));
155 if (sizeof(T) == sizeof(quint32)) {
156 // Microsoft Visual Studio uses unsigned long, but that's still 32-bit
157 generate(begin: reinterpret_cast<quint32 *>(begin), end: reinterpret_cast<quint32 *>(end));
158 } else {
159 // Slow path. Fix your C++ library.
160 std::generate(begin, end, [this]() {
161 quint32 datum;
162 generate(begin: &datum, end: &datum + 1);
163 return datum;
164 });
165 }
166 }
167};
168
169#if defined(Q_OS_WIN)
170static void fallback_update_seed(unsigned) {}
171static void fallback_fill(quint32 *ptr, qsizetype left) noexcept
172{
173 // on Windows, rand_s is a high-quality random number generator
174 // and it requires no seeding
175 std::generate(ptr, ptr + left, []() {
176 unsigned value;
177 rand_s(&value);
178 return value;
179 });
180}
181#elif QT_CONFIG(getentropy)
182static void fallback_update_seed(unsigned) {}
183static void fallback_fill(quint32 *, qsizetype) noexcept
184{
185 // no fallback necessary, getentropy cannot fail under normal circumstances
186 Q_UNREACHABLE();
187}
188#elif defined(Q_OS_BSD4) && !defined(__GLIBC__)
189static void fallback_update_seed(unsigned) {}
190static void fallback_fill(quint32 *ptr, qsizetype left) noexcept
191{
192 // BSDs have arc4random(4) and these work even in chroot(2)
193 arc4random_buf(ptr, left * sizeof(*ptr));
194}
195#else
196Q_CONSTINIT static QBasicAtomicInteger<unsigned> seed = Q_BASIC_ATOMIC_INITIALIZER(0U);
197static void fallback_update_seed(unsigned value)
198{
199 // Update the seed to be used for the fallback mechanism, if we need to.
200 // We can't use QtPrivate::QHashCombine here because that is not an atomic
201 // operation. A simple XOR will have to do then.
202 seed.fetchAndXorRelaxed(value);
203}
204
205Q_NEVER_INLINE
206#ifdef Q_CC_GNU
207__attribute__((cold)) // this function is pretty big, so optimize for size
208#endif
209static void fallback_fill(quint32 *ptr, qsizetype left) noexcept
210{
211 quint32 scratch[12]; // see element count below
212 quint32 *end = scratch;
213
214 auto foldPointer = [](quintptr v) {
215 if (sizeof(quintptr) == sizeof(quint32)) {
216 // For 32-bit systems, we simply return the pointer.
217 return quint32(v);
218 } else {
219 // For 64-bit systems, we try to return the variable part of the
220 // pointer. On current x86-64 and AArch64, the top 17 bits are
221 // architecturally required to be the same, but in reality the top
222 // 24 bits on Linux are likely to be the same for all processes.
223 return quint32(v >> (32 - 24));
224 }
225 };
226
227 Q_ASSERT(left);
228
229 *end++ = foldPointer(quintptr(&seed)); // 1: variable in this library/executable's .data
230 *end++ = foldPointer(quintptr(&scratch)); // 2: variable in the stack
231 *end++ = foldPointer(quintptr(&errno)); // 3: veriable either in libc or thread-specific
232 *end++ = foldPointer(quintptr(reinterpret_cast<void*>(strerror))); // 4: function in libc (and unlikely to be a macro)
233
234#ifndef QT_BOOTSTRAPPED
235 quint64 nsecs = QDeadlineTimer::current(Qt::PreciseTimer).deadline();
236 *end++ = quint32(nsecs); // 5
237#endif
238
239 if (quint32 v = seed.loadRelaxed())
240 *end++ = v; // 6
241
242#if QT_CONFIG(getauxval)
243 // works on Linux -- all modern libc have getauxval
244# ifdef AT_RANDOM
245 // ELF's auxv AT_RANDOM has 16 random bytes
246 // (other ELF-based systems don't seem to have AT_RANDOM)
247 ulong auxvSeed = getauxval(AT_RANDOM);
248 if (auxvSeed) {
249 memcpy(end, reinterpret_cast<void *>(auxvSeed), 16);
250 end += 4; // 7 to 10
251 }
252# endif
253
254 // Both AT_BASE and AT_SYSINFO_EHDR have some randomness in them due to the
255 // system's ASLR, even if many bits are the same. They also have randomness
256 // between them.
257# ifdef AT_BASE
258 // present at least on the BSDs too, indicates the address of the loader
259 ulong base = getauxval(AT_BASE);
260 if (base)
261 *end++ = foldPointer(base); // 11
262# endif
263# ifdef AT_SYSINFO_EHDR
264 // seems to be Linux-only, indicates the global page of the sysinfo
265 ulong sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
266 if (sysinfo_ehdr)
267 *end++ = foldPointer(sysinfo_ehdr); // 12
268# endif
269#endif
270
271 Q_ASSERT(end <= std::end(scratch));
272
273 // this is highly inefficient, we should save the generator across calls...
274 std::seed_seq sseq(scratch, end);
275 std::mt19937 generator(sseq);
276 std::generate(ptr, ptr + left, generator);
277
278 fallback_update_seed(*ptr);
279}
280#endif
281
282Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, quint32 *end)
283 noexcept(FillBufferNoexcept)
284{
285 quint32 *buffer = begin;
286 qsizetype count = end - begin;
287
288 if (Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & SetRandomData)) {
289 uint value = uint(qt_randomdevice_control.loadAcquire()) & RandomDataMask;
290 std::fill_n(first: buffer, n: count, value: value);
291 return;
292 }
293
294 qsizetype filled = 0;
295 if (qHasHwrng() && (uint(qt_randomdevice_control.loadAcquire()) & SkipHWRNG) == 0)
296 filled += qRandomCpu(buffer, count);
297
298 if (filled != count && (uint(qt_randomdevice_control.loadAcquire()) & SkipSystemRNG) == 0) {
299 qsizetype bytesFilled =
300 fillBuffer(buffer: buffer + filled, count: (count - filled) * qsizetype(sizeof(*buffer)));
301 filled += bytesFilled / qsizetype(sizeof(*buffer));
302 }
303 if (filled)
304 fallback_update_seed(*buffer);
305
306 if (Q_UNLIKELY(filled != count)) {
307 // failed to fill the entire buffer, try the faillback mechanism
308 fallback_fill(buffer + filled, count - filled);
309 }
310}
311
312struct QRandomGenerator::SystemAndGlobalGenerators
313{
314 // Construction notes:
315 // 1) The global PRNG state is in a different cacheline compared to the
316 // mutex that protects it. This avoids any false cacheline sharing of
317 // the state in case another thread tries to lock the mutex. It's not
318 // a common scenario, but since sizeof(QRandomGenerator) >= 2560, the
319 // overhead is actually acceptable.
320 // 2) We use both alignas(T) and alignas(64) because some implementations
321 // can't align to more than a primitive type's alignment.
322 // 3) We don't store the entire system QRandomGenerator, only the space
323 // used by the QRandomGenerator::type member. This is fine because we
324 // (ab)use the common initial sequence exclusion to aliasing rules.
325 QBasicMutex globalPRNGMutex;
326 struct ShortenedSystem { uint type; } system_;
327 SystemGenerator sys;
328 alignas(64) struct {
329 alignas(QRandomGenerator64) uchar data[sizeof(QRandomGenerator64)];
330 } global_;
331
332 constexpr SystemAndGlobalGenerators()
333 : globalPRNGMutex{}, system_{.type: 0}, sys{}, global_{}
334 {}
335
336 void confirmLiteral()
337 {
338#if !defined(Q_OS_INTEGRITY)
339 // Integrity's compiler is unable to guarantee g's alignment for some reason.
340 constexpr SystemAndGlobalGenerators g = {};
341 Q_UNUSED(g);
342#endif
343 }
344
345 static SystemAndGlobalGenerators *self()
346 {
347 Q_CONSTINIT static SystemAndGlobalGenerators g;
348 static_assert(sizeof(g) > sizeof(QRandomGenerator64));
349 return &g;
350 }
351
352 static QRandomGenerator64 *system()
353 {
354 // Though we never call the constructor, the system QRandomGenerator is
355 // properly initialized by the zero initialization performed in self().
356 // Though QRandomGenerator is has non-vacuous initialization, we
357 // consider it initialized because of the common initial sequence.
358 return reinterpret_cast<QRandomGenerator64 *>(&self()->system_);
359 }
360
361 static QRandomGenerator64 *globalNoInit()
362 {
363 // This function returns the pointer to the global QRandomGenerator,
364 // but does not initialize it. Only call it directly if you meant to do
365 // a pointer comparison.
366 return reinterpret_cast<QRandomGenerator64 *>(&self()->global_);
367 }
368
369 static void securelySeed(QRandomGenerator *rng)
370 {
371 // force reconstruction, just to be pedantic
372 new (rng) QRandomGenerator{System{}};
373
374 rng->type = MersenneTwister;
375 new (&rng->storage.engine()) RandomEngine(self()->sys);
376 }
377
378 struct PRNGLocker
379 {
380 const bool locked;
381 PRNGLocker(const QRandomGenerator *that)
382 : locked(that == globalNoInit())
383 {
384 if (locked)
385 self()->globalPRNGMutex.lock();
386 }
387 ~PRNGLocker()
388 {
389 if (locked)
390 self()->globalPRNGMutex.unlock();
391 }
392 };
393};
394
395inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::self()
396{
397 return SystemAndGlobalGenerators::self()->sys;
398}
399
400/*!
401 \class QRandomGenerator
402 \inmodule QtCore
403 \reentrant
404 \since 5.10
405
406 \brief The QRandomGenerator class allows one to obtain random values from a
407 high-quality Random Number Generator.
408
409 QRandomGenerator may be used to generate random values from a high-quality
410 random number generator. Like the C++ random engines, QRandomGenerator can
411 be seeded with user-provided values through the constructor.
412 When seeded, the sequence of numbers generated by this
413 class is deterministic. That is to say, given the same seed data,
414 QRandomGenerator will generate the same sequence of numbers. But given
415 different seeds, the results should be considerably different.
416
417 QRandomGenerator::securelySeeded() can be used to create a QRandomGenerator
418 that is securely seeded with QRandomGenerator::system(), meaning that the
419 sequence of numbers it generates cannot be easily predicted. Additionally,
420 QRandomGenerator::global() returns a global instance of QRandomGenerator
421 that Qt will ensure to be securely seeded. This object is thread-safe, may
422 be shared for most uses, and is always seeded from
423 QRandomGenerator::system()
424
425 QRandomGenerator::system() may be used to access the system's
426 cryptographically-safe random generator. On Unix systems, it's equivalent
427 to reading from \c {/dev/urandom} or the \c {getrandom()} or \c
428 {getentropy()} system calls.
429
430 The class can generate 32-bit or 64-bit quantities, or fill an array of
431 those. The most common way of generating new values is to call the generate(),
432 generate64() or fillRange() functions. One would use it as:
433
434 \snippet code/src_corelib_global_qrandom.cpp 0
435
436 Additionally, it provides a floating-point function generateDouble() that
437 returns a number in the range [0, 1) (that is, inclusive of zero and
438 exclusive of 1). There's also a set of convenience functions that
439 facilitate obtaining a random number in a bounded, integral range.
440
441 \section1 Seeding and determinism
442
443 QRandomGenerator may be seeded with specific seed data. When that is done,
444 the numbers generated by the object will always be the same, as in the
445 following example:
446
447 \snippet code/src_corelib_global_qrandom.cpp 1
448
449 The seed data takes the form of one or more 32-bit words. The ideal seed
450 size is approximately equal to the size of the QRandomGenerator class
451 itself. Due to mixing of the seed data, QRandomGenerator cannot guarantee
452 that distinct seeds will produce different sequences.
453
454 QRandomGenerator::global(), like all generators created by
455 QRandomGenerator::securelySeeded(), is always seeded from
456 QRandomGenerator::system(), so it's not possible to make it produce
457 identical sequences.
458
459 \section1 Bulk data
460
461 When operating in deterministic mode, QRandomGenerator may be used for bulk
462 data generation. In fact, applications that do not need
463 cryptographically-secure or true random data are advised to use a regular
464 QRandomGenerator instead of QRandomGenerator::system() for their random
465 data needs.
466
467 For ease of use, QRandomGenerator provides a global object that can
468 be easily used, as in the following example:
469
470 \snippet code/src_corelib_global_qrandom.cpp 2
471
472 \section1 System-wide random number generator
473
474 QRandomGenerator::system() may be used to access the system-wide random
475 number generator, which is cryptographically-safe on all systems that Qt
476 runs on. This function will use hardware facilities to generate random
477 numbers where available. On such systems, those facilities are true Random
478 Number Generators. However, if they are true RNGs, those facilities have
479 finite entropy sources and thus may fail to produce any results if their
480 entropy pool is exhausted.
481
482 If that happens, first the operating system then QRandomGenerator will fall
483 back to Pseudo Random Number Generators of decreasing qualities (Qt's
484 fallback generator being the simplest). Whether those generators are still
485 of cryptographic quality is implementation-defined. Therefore,
486 QRandomGenerator::system() should not be used for high-frequency random
487 number generation, lest the entropy pool become empty. As a rule of thumb,
488 this class should not be called upon to generate more than a kilobyte per
489 second of random data (note: this may vary from system to system).
490
491 If an application needs true RNG data in bulk, it should use the operating
492 system facilities (such as \c{/dev/random} on Linux) directly and wait for
493 entropy to become available. If the application requires PRNG engines of
494 cryptographic quality but not of true randomness,
495 QRandomGenerator::system() may still be used (see section below).
496
497 If neither a true RNG nor a cryptographically secure PRNG are required,
498 applications should instead use PRNG engines like QRandomGenerator's
499 deterministic mode and those from the C++ Standard Library.
500 QRandomGenerator::system() can be used to seed those.
501
502 \section2 Fallback quality
503
504 QRandomGenerator::system() uses the operating system facilities to obtain
505 random numbers, which attempt to collect real entropy from the surrounding
506 environment to produce true random numbers. However, it's possible that the
507 entropy pool becomes exhausted, in which case the operating system will
508 fall back to a pseudo-random engine for a time. Under no circumstances will
509 QRandomGenerator::system() block, waiting for more entropy to be collected.
510
511 The following operating systems guarantee that the results from their
512 random-generation API will be of at least cryptographically-safe quality,
513 even if the entropy pool is exhausted: Apple OSes (Darwin), BSDs, Linux,
514 Windows. Barring a system installation problem (such as \c{/dev/urandom}
515 not being readable by the current process), QRandomGenerator::system() will
516 therefore have the same guarantees.
517
518 On other operating systems, QRandomGenerator will fall back to a PRNG of
519 good numeric distribution, but it cannot guarantee proper seeding in all
520 cases. Please consult the OS documentation for more information.
521
522 Applications that require QRandomGenerator not to fall back to
523 non-cryptographic quality generators are advised to check their operating
524 system documentation or restrict their deployment to one of the above.
525
526 \section1 Reentrancy and thread-safety
527
528 QRandomGenerator is reentrant, meaning that multiple threads can operate on
529 this class at the same time, so long as they operate on different objects.
530 If multiple threads need to share one PRNG sequence, external locking by a
531 mutex is required.
532
533 The exceptions are the objects returned by QRandomGenerator::global() and
534 QRandomGenerator::system(): those objects are thread-safe and may be used
535 by any thread without external locking. Note that thread-safety does not
536 extend to copying those objects: they should always be used by reference.
537
538 \section1 Standard C++ Library compatibility
539
540 QRandomGenerator is modeled after the requirements for random number
541 engines in the C++ Standard Library and may be used in almost all contexts
542 that the Standard Library engines can. Exceptions to the requirements are
543 the following:
544
545 \list
546 \li QRandomGenerator does not support seeding from another seed
547 sequence-like class besides std::seed_seq itself;
548 \li QRandomGenerator is not comparable (but is copyable) or
549 streamable to \c{std::ostream} or from \c{std::istream}.
550 \endlist
551
552 QRandomGenerator is also compatible with the uniform distribution classes
553 \c{std::uniform_int_distribution} and \c{std:uniform_real_distribution}, as
554 well as the free function \c{std::generate_canonical}. For example, the
555 following code may be used to generate a floating-point number in the range
556 [1, 2.5):
557
558 \snippet code/src_corelib_global_qrandom.cpp 3
559
560 \sa QRandomGenerator64
561 */
562
563/*!
564 \enum QRandomGenerator::System
565 \internal
566*/
567
568/*!
569 \fn QRandomGenerator::QRandomGenerator(quint32 seedValue)
570
571 Initializes this QRandomGenerator object with the value \a seedValue as
572 the seed. Two objects constructed or reseeded with the same seed value will
573 produce the same number sequence.
574
575 \sa seed(), securelySeeded()
576 */
577
578/*!
579 \fn template <qsizetype N> QRandomGenerator::QRandomGenerator(const quint32 (&seedBuffer)[N])
580 \overload
581
582 Initializes this QRandomGenerator object with the values found in the
583 array \a seedBuffer as the seed. Two objects constructed or reseeded with
584 the same seed value will produce the same number sequence.
585
586 \sa seed(), securelySeeded()
587 */
588
589/*!
590 \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qsizetype len)
591 \overload
592
593 Initializes this QRandomGenerator object with \a len values found in
594 the array \a seedBuffer as the seed. Two objects constructed or reseeded
595 with the same seed value will produce the same number sequence.
596
597 This constructor is equivalent to:
598 \snippet code/src_corelib_global_qrandom.cpp 4
599
600 \sa seed(), securelySeeded()
601 */
602
603/*!
604 \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
605 \overload
606
607 Initializes this QRandomGenerator object with the values found in the range
608 from \a begin to \a end as the seed. Two objects constructed or reseeded
609 with the same seed value will produce the same number sequence.
610
611 This constructor is equivalent to:
612 \snippet code/src_corelib_global_qrandom.cpp 5
613
614 \sa seed(), securelySeeded()
615 */
616
617/*!
618 \fn QRandomGenerator::QRandomGenerator(std::seed_seq &sseq)
619 \overload
620
621 Initializes this QRandomGenerator object with the seed sequence \a
622 sseq as the seed. Two objects constructed or reseeded with the same seed
623 value will produce the same number sequence.
624
625 \sa seed(), securelySeeded()
626 */
627
628/*!
629 \fn QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
630
631 Creates a copy of the generator state in the \a other object. If \a other is
632 QRandomGenerator::system() or a copy of that, this object will also read
633 from the operating system random-generating facilities. In that case, the
634 sequences generated by the two objects will be different.
635
636 In all other cases, the new QRandomGenerator object will start at the same
637 position in the deterministic sequence as the \a other object was. Both
638 objects will generate the same sequence from this point on.
639
640 For that reason, it is not advisable to create a copy of
641 QRandomGenerator::global(). If one needs an exclusive deterministic
642 generator, consider instead using securelySeeded() to obtain a new object
643 that shares no relationship with the QRandomGenerator::global().
644 */
645
646/*!
647 \fn bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
648 \relates QRandomGenerator
649
650 Returns true if the two engines \a rng1 and \a rng2 are at the same
651 state or if they are both reading from the operating system facilities,
652 false otherwise.
653*/
654
655/*!
656 \fn bool QRandomGenerator::operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
657
658 Returns \c true if the two engines \a rng1 and \a rng2 are at
659 different states or if one of them is reading from the operating system
660 facilities and the other is not, \c false otherwise.
661*/
662
663/*!
664 \typedef QRandomGenerator::result_type
665
666 A typedef to the type that operator() returns. That is, quint32.
667
668 \sa operator()
669 */
670
671/*!
672 \fn result_type QRandomGenerator::operator()()
673
674 Generates a 32-bit random quantity and returns it.
675
676 \sa generate(), generate64()
677 */
678
679/*!
680 \fn quint32 QRandomGenerator::generate()
681
682 Generates a 32-bit random quantity and returns it.
683
684 \sa {QRandomGenerator::operator()}{operator()()}, generate64()
685 */
686
687/*!
688 \fn quint64 QRandomGenerator::generate64()
689
690 Generates a 64-bit random quantity and returns it.
691
692 \sa {QRandomGenerator::operator()}{operator()()}, generate()
693 */
694
695/*!
696 \fn result_type QRandomGenerator::min()
697
698 Returns the minimum value that QRandomGenerator may ever generate. That is, 0.
699
700 \sa max(), QRandomGenerator64::min()
701 */
702
703/*!
704 \fn result_type QRandomGenerator::max()
705
706 Returns the maximum value that QRandomGenerator may ever generate. That is,
707 \c {std::numeric_limits<result_type>::max()}.
708
709 \sa min(), QRandomGenerator64::max()
710 */
711
712/*!
713 \fn void QRandomGenerator::seed(quint32 seed)
714
715 Reseeds this object using the value \a seed as the seed.
716 */
717
718/*!
719 \fn void QRandomGenerator::seed(std::seed_seq &seed)
720 \overload
721
722 Reseeds this object using the seed sequence \a seed as the seed.
723 */
724
725/*!
726 \fn void QRandomGenerator::discard(unsigned long long z)
727
728 Discards the next \a z entries from the sequence. This method is equivalent
729 to calling generate() \a z times and discarding the result, as in:
730
731 \snippet code/src_corelib_global_qrandom.cpp 6
732*/
733
734/*!
735 \fn template <typename ForwardIterator> void QRandomGenerator::generate(ForwardIterator begin, ForwardIterator end)
736
737 Generates 32-bit quantities and stores them in the range between \a begin
738 and \a end. This function is equivalent to (and is implemented as):
739
740 \snippet code/src_corelib_global_qrandom.cpp 7
741
742 This function complies with the requirements for the function
743 \l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq/generate}{\c std::seed_seq::generate},
744 which requires unsigned 32-bit integer values.
745
746 Note that if the [begin, end) range refers to an area that can store more
747 than 32 bits per element, the elements will still be initialized with only
748 32 bits of data. Any other bits will be zero. To fill the range with 64 bit
749 quantities, one can write:
750
751 \snippet code/src_corelib_global_qrandom.cpp 8
752
753 If the range refers to contiguous memory (such as an array or the data from
754 a QList), the fillRange() function may be used too.
755
756 \sa fillRange()
757 */
758
759/*!
760 \fn void QRandomGenerator::generate(quint32 *begin, quint32 *end)
761 \overload
762 \internal
763
764 Same as the other overload, but more efficiently fills \a begin to \a end.
765 */
766
767/*!
768 \fn template <typename UInt> void QRandomGenerator::fillRange(UInt *buffer, qsizetype count)
769
770 Generates \a count 32- or 64-bit quantities (depending on the type \c UInt)
771 and stores them in the buffer pointed by \a buffer. This is the most
772 efficient way to obtain more than one quantity at a time, as it reduces the
773 number of calls into the Random Number Generator source.
774
775 For example, to fill a list of 16 entries with random values, one may
776 write:
777
778 \snippet code/src_corelib_global_qrandom.cpp 9
779
780 \sa generate()
781 */
782
783/*!
784 \fn template <typename UInt, size_t N> void QRandomGenerator::fillRange(UInt (&buffer)[N])
785
786 Generates \c N 32- or 64-bit quantities (depending on the type \c UInt) and
787 stores them in the \a buffer array. This is the most efficient way to
788 obtain more than one quantity at a time, as it reduces the number of calls
789 into the Random Number Generator source.
790
791 For example, to fill generate two 32-bit quantities, one may write:
792
793 \snippet code/src_corelib_global_qrandom.cpp 10
794
795 It would have also been possible to make one call to generate64() and then split
796 the two halves of the 64-bit value.
797
798 \sa generate()
799 */
800
801/*!
802 \fn qreal QRandomGenerator::generateDouble()
803
804 Generates one random qreal in the canonical range [0, 1) (that is,
805 inclusive of zero and exclusive of 1).
806
807 This function is equivalent to:
808 \snippet code/src_corelib_global_qrandom.cpp 11
809
810 The same may also be obtained by using
811 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution}{\c std::uniform_real_distribution}
812 with parameters 0 and 1.
813
814 \sa generate(), generate64(), bounded()
815 */
816
817/*!
818 \fn double QRandomGenerator::bounded(double highest)
819
820 Generates one random double in the range between 0 (inclusive) and \a
821 highest (exclusive). This function is equivalent to and is implemented as:
822
823 \snippet code/src_corelib_global_qrandom.cpp 12
824
825 If the \a highest parameter is negative, the result will be negative too;
826 if it is infinite or NaN, the result will be infinite or NaN too (that is,
827 not random).
828
829 \sa generateDouble(), bounded()
830 */
831
832/*!
833 \fn quint32 QRandomGenerator::bounded(quint32 highest)
834 \overload
835
836 Generates one random 32-bit quantity in the range between 0 (inclusive) and
837 \a highest (exclusive). The same result may also be obtained by using
838 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution}
839 with parameters 0 and \c{highest - 1}. That class can also be used to obtain
840 quantities larger than 32 bits; for 64 bits, the 64-bit bounded() overload
841 can be used too.
842
843 For example, to obtain a value between 0 and 255 (inclusive), one would write:
844
845 \snippet code/src_corelib_global_qrandom.cpp 13
846
847 Naturally, the same could also be obtained by masking the result of generate()
848 to only the lower 8 bits. Either solution is as efficient.
849
850 Note that this function cannot be used to obtain values in the full 32-bit
851 range of quint32. Instead, use generate().
852
853 \sa generate(), generate64(), generateDouble()
854 */
855
856/*!
857 \fn int QRandomGenerator::bounded(int highest)
858 \overload
859
860 Generates one random 32-bit quantity in the range between 0 (inclusive) and
861 \a highest (exclusive). \a highest must be positive.
862
863 Note that this function cannot be used to obtain values in the full 32-bit
864 range of int. Instead, use generate() and cast to int.
865
866 \sa generate(), generate64(), generateDouble()
867 */
868
869/*!
870 \fn quint64 QRandomGenerator::bounded(quint64 highest)
871 \overload
872
873 Generates one random 64-bit quantity in the range between 0 (inclusive) and
874 \a highest (exclusive). The same result may also be obtained by using
875 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution<quint64>}
876 with parameters 0 and \c{highest - 1}.
877
878 Note that this function cannot be used to obtain values in the full 64-bit
879 range of \c{quint64}. Instead, use generate64().
880
881 \note This function is implemented as a loop, which depends on the random
882 value obtained. On the long run, on average it should loop just under 2
883 times, but if the random generator is defective, this function may take
884 considerably longer to execute.
885
886 \sa generate(), generate64(), generateDouble()
887 */
888
889/*!
890 \fn qint64 QRandomGenerator::bounded(qint64 highest)
891 \overload
892
893 Generates one random 64-bit quantity in the range between 0 (inclusive) and
894 \a highest (exclusive). \a highest must be positive.
895
896 Note that this function cannot be used to obtain values in the full 64-bit
897 range of \c{qint64}. Instead, use generate64() and cast to qint64 or instead
898 use the unsigned version of this function.
899
900 \note This function is implemented as a loop, which depends on the random
901 value obtained. On the long run, on average it should loop just under 2
902 times, but if the random generator is defective, this function may take
903 considerably longer to execute.
904
905 \sa generate(), generate64(), generateDouble()
906 */
907
908/*!
909 \fn quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest)
910 \overload
911
912 Generates one random 32-bit quantity in the range between \a lowest
913 (inclusive) and \a highest (exclusive). The \a highest parameter must be
914 greater than \a lowest.
915
916 The same result may also be obtained by using
917 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution}
918 with parameters \a lowest and \c{\a highest - 1}. That class can also be used to
919 obtain quantities larger than 32 bits.
920
921 For example, to obtain a value between 1000 (incl.) and 2000 (excl.), one
922 would write:
923
924 \snippet code/src_corelib_global_qrandom.cpp 14
925
926 Note that this function cannot be used to obtain values in the full 32-bit
927 range of quint32. Instead, use generate().
928
929 \sa generate(), generate64(), generateDouble()
930 */
931
932/*!
933 \fn int QRandomGenerator::bounded(int lowest, int highest)
934 \overload
935
936 Generates one random 32-bit quantity in the range between \a lowest
937 (inclusive) and \a highest (exclusive), both of which may be negative, but
938 \a highest must be greater than \a lowest.
939
940 Note that this function cannot be used to obtain values in the full 32-bit
941 range of int. Instead, use generate() and cast to int.
942
943 \sa generate(), generate64(), generateDouble()
944 */
945
946/*!
947 \fn quint64 QRandomGenerator::bounded(quint64 lowest, quint64 highest)
948 \overload
949
950 Generates one random 64-bit quantity in the range between \a lowest
951 (inclusive) and \a highest (exclusive). The \a highest parameter must be
952 greater than \a lowest.
953
954 The same result may also be obtained by using
955 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution<quint64>}
956 with parameters \a lowest and \c{\a highest - 1}.
957
958 Note that this function cannot be used to obtain values in the full 64-bit
959 range of \c{quint64}. Instead, use generate64().
960
961 \note This function is implemented as a loop, which depends on the random
962 value obtained. On the long run, on average it should loop just under 2
963 times, but if the random generator is defective, this function may take
964 considerably longer to execute.
965
966 \sa generate(), generate64(), generateDouble()
967 */
968
969/*!
970 \fn qint64 QRandomGenerator::bounded(qint64 lowest, qint64 highest)
971 \overload
972
973 Generates one random 64-bit quantity in the range between \a lowest
974 (inclusive) and \a highest (exclusive), both of which may be negative, but
975 \a highest must be greater than \a lowest.
976
977 Note that this function cannot be used to obtain values in the full 64-bit
978 range of \c{qint64}. Instead, use generate64() and cast to qint64.
979
980 \note This function is implemented as a loop, which depends on the random
981 value obtained. On the long run, on average it should loop just under 2
982 times, but if the random generator is defective, this function may take
983 considerably longer to execute.
984
985 \sa generate(), generate64(), generateDouble()
986 */
987
988/*!
989 \fn qint64 QRandomGenerator::bounded(int lowest, qint64 highest)
990 \fn qint64 QRandomGenerator::bounded(qint64 lowest, int highest)
991 \fn quint64 QRandomGenerator::bounded(unsigned lowest, quint64 highest)
992 \fn quint64 QRandomGenerator::bounded(quint64 lowest, unsigned highest)
993 \overload
994
995 This function exists to help with overload resolution when the types of the
996 parameters don't exactly match. They will promote the smaller type to the
997 type of the larger one and call the correct overload.
998 */
999
1000/*!
1001 \fn QRandomGenerator *QRandomGenerator::system()
1002 \threadsafe
1003
1004 Returns a pointer to a shared QRandomGenerator that always uses the
1005 facilities provided by the operating system to generate random numbers. The
1006 system facilities are considered to be cryptographically safe on at least
1007 the following operating systems: Apple OSes (Darwin), BSDs, Linux, Windows.
1008 That may also be the case on other operating systems.
1009
1010 They are also possibly backed by a true hardware random number generator.
1011 For that reason, the QRandomGenerator returned by this function should not
1012 be used for bulk data generation. Instead, use it to seed QRandomGenerator
1013 or a random engine from the <random> header.
1014
1015 The object returned by this function is thread-safe and may be used in any
1016 thread without locks. It may also be copied and the resulting
1017 QRandomGenerator will also access the operating system facilities, but they
1018 will not generate the same sequence.
1019
1020 \sa securelySeeded(), global()
1021*/
1022
1023/*!
1024 \fn QRandomGenerator *QRandomGenerator::global()
1025 \threadsafe
1026
1027 Returns a pointer to a shared QRandomGenerator that was seeded using
1028 securelySeeded(). This function should be used to create random data
1029 without the expensive creation of a securely-seeded QRandomGenerator
1030 for a specific use or storing the rather large QRandomGenerator object.
1031
1032 For example, the following creates a random RGB color:
1033
1034 \snippet code/src_corelib_global_qrandom.cpp 15
1035
1036 Accesses to this object are thread-safe and it may therefore be used in any
1037 thread without locks. The object may also be copied and the sequence
1038 produced by the copy will be the same as the shared object will produce.
1039 Note, however, that if there are other threads accessing the global object,
1040 those threads may obtain samples at unpredictable intervals.
1041
1042 \sa securelySeeded(), system()
1043*/
1044
1045/*!
1046 \fn QRandomGenerator QRandomGenerator::securelySeeded()
1047
1048 Returns a new QRandomGenerator object that was securely seeded with
1049 QRandomGenerator::system(). This function will obtain the ideal seed size
1050 for the algorithm that QRandomGenerator uses and is therefore the
1051 recommended way for creating a new QRandomGenerator object that will be
1052 kept for some time.
1053
1054 Given the amount of data required to securely seed the deterministic
1055 engine, this function is somewhat expensive and should not be used for
1056 short-term uses of QRandomGenerator (using it to generate fewer than 2600
1057 bytes of random data is effectively a waste of resources). If the use
1058 doesn't require that much data, consider using QRandomGenerator::global()
1059 and not storing a QRandomGenerator object instead.
1060
1061 \sa global(), system()
1062 */
1063
1064/*!
1065 \class QRandomGenerator64
1066 \inmodule QtCore
1067 \since 5.10
1068
1069 \brief The QRandomGenerator64 class allows one to obtain 64-bit random values
1070 from a high-quality, seed-less Random Number Generator.
1071
1072 QRandomGenerator64 is a simple adaptor class around QRandomGenerator, making the
1073 QRandomGenerator::generate64() function the default for operator()(), instead of the
1074 function that returns 32-bit quantities. This class is intended to be used
1075 in conjunction with Standard Library algorithms that need 64-bit quantities
1076 instead of 32-bit ones.
1077
1078 In all other aspects, the class is the same. Please refer to
1079 QRandomGenerator's documentation for more information.
1080
1081 \sa QRandomGenerator
1082*/
1083
1084/*!
1085 \typedef QRandomGenerator64::result_type
1086
1087 A typedef to the type that operator() returns. That is, quint64.
1088
1089 \sa operator()
1090 */
1091
1092/*!
1093 \fn quint64 QRandomGenerator64::generate()
1094
1095 Generates one 64-bit random value and returns it.
1096
1097 Note about casting to a signed integer: all bits returned by this function
1098 are random, so there's a 50% chance that the most significant bit will be
1099 set. If you wish to cast the returned value to qint64 and keep it positive,
1100 you should mask the sign bit off:
1101
1102 \snippet code/src_corelib_global_qrandom.cpp 16
1103
1104 \sa QRandomGenerator, QRandomGenerator::generate64()
1105 */
1106
1107/*!
1108 \fn result_type QRandomGenerator64::operator()()
1109
1110 Generates a 64-bit random quantity and returns it.
1111
1112 \sa QRandomGenerator::generate(), QRandomGenerator::generate64()
1113 */
1114
1115constexpr QRandomGenerator::Storage::Storage()
1116 : dummy(0)
1117{
1118 // nothing
1119}
1120
1121inline QRandomGenerator64::QRandomGenerator64(System s)
1122 : QRandomGenerator(s)
1123{
1124}
1125
1126QRandomGenerator64 *QRandomGenerator64::system()
1127{
1128 auto self = SystemAndGlobalGenerators::system();
1129 Q_ASSERT(self->type == SystemRNG);
1130 return self;
1131}
1132
1133QRandomGenerator64 *QRandomGenerator64::global()
1134{
1135 auto self = SystemAndGlobalGenerators::globalNoInit();
1136
1137 // Yes, this is a double-checked lock.
1138 // We can return even if the type is not completely initialized yet:
1139 // any thread trying to actually use the contents of the random engine
1140 // will necessarily wait on the lock.
1141 if (Q_LIKELY(self->type != SystemRNG))
1142 return self;
1143
1144 SystemAndGlobalGenerators::PRNGLocker locker(self);
1145 if (self->type == SystemRNG)
1146 SystemAndGlobalGenerators::securelySeed(rng: self);
1147
1148 return self;
1149}
1150
1151QRandomGenerator64 QRandomGenerator64::securelySeeded()
1152{
1153 QRandomGenerator64 result(System{});
1154 SystemAndGlobalGenerators::securelySeed(rng: &result);
1155 return result;
1156}
1157
1158/*!
1159 \internal
1160*/
1161inline QRandomGenerator::QRandomGenerator(System)
1162 : type(SystemRNG)
1163{
1164 // don't touch storage
1165}
1166
1167QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
1168 : type(other.type)
1169{
1170 Q_ASSERT(this != system());
1171 Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit());
1172
1173 if (type != SystemRNG) {
1174 SystemAndGlobalGenerators::PRNGLocker lock(&other);
1175 storage.engine() = other.storage.engine();
1176 }
1177}
1178
1179QRandomGenerator &QRandomGenerator::operator=(const QRandomGenerator &other)
1180{
1181 if (Q_UNLIKELY(this == system()) || Q_UNLIKELY(this == SystemAndGlobalGenerators::globalNoInit()))
1182 qFatal(msg: "Attempted to overwrite a QRandomGenerator to system() or global().");
1183
1184 if ((type = other.type) != SystemRNG) {
1185 SystemAndGlobalGenerators::PRNGLocker lock(&other);
1186 storage.engine() = other.storage.engine();
1187 }
1188 return *this;
1189}
1190
1191QRandomGenerator::QRandomGenerator(std::seed_seq &sseq) noexcept
1192 : type(MersenneTwister)
1193{
1194 Q_ASSERT(this != system());
1195 Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit());
1196
1197 new (&storage.engine()) RandomEngine(sseq);
1198}
1199
1200QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
1201 : type(MersenneTwister)
1202{
1203 Q_ASSERT(this != system());
1204 Q_ASSERT(this != SystemAndGlobalGenerators::globalNoInit());
1205
1206 std::seed_seq s(begin, end);
1207 new (&storage.engine()) RandomEngine(s);
1208}
1209
1210void QRandomGenerator::discard(unsigned long long z)
1211{
1212 if (Q_UNLIKELY(type == SystemRNG))
1213 return;
1214
1215 SystemAndGlobalGenerators::PRNGLocker lock(this);
1216 storage.engine().discard(z: z);
1217}
1218
1219bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
1220{
1221 if (rng1.type != rng2.type)
1222 return false;
1223 if (rng1.type == SystemRNG)
1224 return true;
1225
1226 // Lock global() if either is it (otherwise this locking is a no-op)
1227 using PRNGLocker = QRandomGenerator::SystemAndGlobalGenerators::PRNGLocker;
1228 PRNGLocker locker(&rng1 == QRandomGenerator::global() ? &rng1 : &rng2);
1229 return rng1.storage.engine() == rng2.storage.engine();
1230}
1231
1232/*!
1233 \internal
1234
1235 Fills the range pointed by \a buffer with \a count 32-bit random values.
1236 The buffer must be correctly aligned.
1237
1238 Returns the value of the first two 32-bit entries as a \c{quint64}.
1239 */
1240quint64 QRandomGenerator::_fillRange(void *buffer, qptrdiff count)
1241{
1242 // Verify that the pointers are properly aligned for 32-bit
1243 Q_ASSERT(quintptr(buffer) % sizeof(quint32) == 0);
1244 Q_ASSERT(count >= 0);
1245 Q_ASSERT(buffer || count <= 2);
1246
1247 quint64 dummy;
1248 quint32 *begin = static_cast<quint32 *>(buffer ? buffer : &dummy);
1249 quint32 *end = begin + count;
1250
1251 if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & (UseSystemRNG|SetRandomData))) {
1252 SystemGenerator::self().generate(begin, end);
1253 } else {
1254 SystemAndGlobalGenerators::PRNGLocker lock(this);
1255 std::generate(first: begin, last: end, gen: [this]() { return storage.engine()(); });
1256 }
1257
1258 if (end - begin == 1)
1259 return *begin;
1260 return begin[0] | (quint64(begin[1]) << 32);
1261}
1262
1263// helper function to call fillBuffer, since we need something to be
1264// argument-dependent
1265template <typename Generator, typename FillBufferType, typename T>
1266static qsizetype callFillBuffer(FillBufferType f, T *v)
1267{
1268 if constexpr (std::is_member_function_pointer_v<FillBufferType>) {
1269 // member function, need an object
1270 return (Generator::self().*f)(v, sizeof(*v));
1271 } else {
1272 // static, call directly
1273 return f(v, sizeof(*v));
1274 }
1275}
1276
1277/*!
1278 \internal
1279
1280 Returns an initial random value (useful for QHash's global seed). This
1281 function attempts to use OS-provided random values to avoid initializing
1282 QRandomGenerator::system() and qsimd.cpp.
1283
1284 Note: on some systems, this functionn may rerturn the same value every time
1285 it is called.
1286 */
1287QRandomGenerator::InitialRandomData qt_initial_random_value() noexcept
1288{
1289#if QT_CONFIG(getauxval) && defined(AT_RANDOM)
1290 auto at_random_ptr = reinterpret_cast<size_t *>(getauxval(AT_RANDOM));
1291 if (at_random_ptr)
1292 return qFromUnaligned<QRandomGenerator::InitialRandomData>(src: at_random_ptr);
1293#endif
1294
1295 // bypass the hardware RNG, which would mean initializing qsimd.cpp
1296
1297 QRandomGenerator::InitialRandomData v;
1298 for (int attempts = 16; attempts; --attempts) {
1299 using Generator = QRandomGenerator::SystemGenerator;
1300 auto fillBuffer = &Generator::fillBuffer;
1301 if (callFillBuffer<Generator>(f: fillBuffer, v: &v) != sizeof(v))
1302 continue;
1303
1304 return v;
1305 }
1306
1307 quint32 data[sizeof(v) / sizeof(quint32)];
1308 fallback_fill(data, std::size(data));
1309 memcpy(dest: v.data, src: data, n: sizeof(v.data));
1310 return v;
1311}
1312
1313QT_END_NAMESPACE
1314

source code of qtbase/src/corelib/global/qrandom.cpp