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