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