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 (qHasHwrng() && (uint(qt_randomdevice_control.loadAcquire()) & SkipHWRNG) == 0)
297 filled += qRandomCpu(buffer, count);
298
299 if (filled != count && (uint(qt_randomdevice_control.loadAcquire()) & SkipSystemRNG) == 0) {
300 qsizetype bytesFilled =
301 fillBuffer(buffer + filled, (count - filled) * qsizetype(sizeof(*buffer)));
302 filled += bytesFilled / qsizetype(sizeof(*buffer));
303 }
304 if (filled)
305 fallback_update_seed(*buffer);
306
307 if (Q_UNLIKELY(filled != count)) {
308 // failed to fill the entire buffer, try the faillback mechanism
309 fallback_fill(buffer + filled, count - filled);
310 }
311}
312
313struct QRandomGenerator::SystemAndGlobalGenerators
314{
315 // Construction notes:
316 // 1) The global PRNG state is in a different cacheline compared to the
317 // mutex that protects it. This avoids any false cacheline sharing of
318 // the state in case another thread tries to lock the mutex. It's not
319 // a common scenario, but since sizeof(QRandomGenerator) >= 2560, the
320 // overhead is actually acceptable.
321 // 2) We use both alignas(T) and alignas(64) because some implementations
322 // can't align to more than a primitive type's alignment.
323 // 3) We don't store the entire system QRandomGenerator, only the space
324 // used by the QRandomGenerator::type member. This is fine because we
325 // (ab)use the common initial sequence exclusion to aliasing rules.
327 struct ShortenedSystem { uint type; } system_;
329 alignas(64) struct {
330 alignas(QRandomGenerator64) uchar data[sizeof(QRandomGenerator64)];
331 } global_;
332
334 : globalPRNGMutex{}, system_{0}, sys{}, global_{}
335 {}
336
338 {
339#if !defined(Q_OS_INTEGRITY)
340 // Integrity's compiler is unable to guarantee g's alignment for some reason.
341 constexpr SystemAndGlobalGenerators g = {};
342 Q_UNUSED(g);
343#endif
344 }
345
347 {
348 Q_CONSTINIT static SystemAndGlobalGenerators g;
349 static_assert(sizeof(g) > sizeof(QRandomGenerator64));
350 return &g;
351 }
352
354 {
355 // Though we never call the constructor, the system QRandomGenerator is
356 // properly initialized by the zero initialization performed in self().
357 // Though QRandomGenerator is has non-vacuous initialization, we
358 // consider it initialized because of the common initial sequence.
359 return reinterpret_cast<QRandomGenerator64 *>(&self()->system_);
360 }
361
363 {
364 // This function returns the pointer to the global QRandomGenerator,
365 // but does not initialize it. Only call it directly if you meant to do
366 // a pointer comparison.
367 return reinterpret_cast<QRandomGenerator64 *>(&self()->global_);
368 }
369
370 static void securelySeed(QRandomGenerator *rng)
371 {
372 // force reconstruction, just to be pedantic
373 new (rng) QRandomGenerator{System{}};
374
375 rng->type = MersenneTwister;
376 new (&rng->storage.engine()) RandomEngine(self()->sys);
377 }
378
380 {
382 const bool locked;
384 : locked(that == globalNoInit())
385 {
386 if (locked)
388 }
390 {
391 if (locked)
392 self()->globalPRNGMutex.unlock();
393 }
394 };
395};
396
397inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::self()
398{
400}
401
402/*!
403 \class QRandomGenerator
404 \inmodule QtCore
405 \reentrant
406 \since 5.10
407
408 \brief The QRandomGenerator class allows one to obtain random values from a
409 high-quality Random Number Generator.
410
411 QRandomGenerator may be used to generate random values from a high-quality
412 random number generator. Like the C++ random engines, QRandomGenerator can
413 be seeded with user-provided values through the constructor.
414 When seeded, the sequence of numbers generated by this
415 class is deterministic. That is to say, given the same seed data,
416 QRandomGenerator will generate the same sequence of numbers. But given
417 different seeds, the results should be considerably different.
418
419 QRandomGenerator::securelySeeded() can be used to create a QRandomGenerator
420 that is securely seeded with QRandomGenerator::system(), meaning that the
421 sequence of numbers it generates cannot be easily predicted. Additionally,
422 QRandomGenerator::global() returns a global instance of QRandomGenerator
423 that Qt will ensure to be securely seeded. This object is thread-safe, may
424 be shared for most uses, and is always seeded from
425 QRandomGenerator::system()
426
427 QRandomGenerator::system() may be used to access the system's
428 cryptographically-safe random generator. On Unix systems, it's equivalent
429 to reading from \c {/dev/urandom} or the \c {getrandom()} or \c
430 {getentropy()} system calls.
431
432 The class can generate 32-bit or 64-bit quantities, or fill an array of
433 those. The most common way of generating new values is to call the generate(),
434 generate64() or fillRange() functions. One would use it as:
435
436 \snippet code/src_corelib_global_qrandom.cpp 0
437
438 Additionally, it provides a floating-point function generateDouble() that
439 returns a number in the range [0, 1) (that is, inclusive of zero and
440 exclusive of 1). There's also a set of convenience functions that
441 facilitate obtaining a random number in a bounded, integral range.
442
443 \section1 Seeding and determinism
444
445 QRandomGenerator may be seeded with specific seed data. When that is done,
446 the numbers generated by the object will always be the same, as in the
447 following example:
448
449 \snippet code/src_corelib_global_qrandom.cpp 1
450
451 The seed data takes the form of one or more 32-bit words. The ideal seed
452 size is approximately equal to the size of the QRandomGenerator class
453 itself. Due to mixing of the seed data, QRandomGenerator cannot guarantee
454 that distinct seeds will produce different sequences.
455
456 QRandomGenerator::global(), like all generators created by
457 QRandomGenerator::securelySeeded(), is always seeded from
458 QRandomGenerator::system(), so it's not possible to make it produce
459 identical sequences.
460
461 \section1 Bulk data
462
463 When operating in deterministic mode, QRandomGenerator may be used for bulk
464 data generation. In fact, applications that do not need
465 cryptographically-secure or true random data are advised to use a regular
466 QRandomGenerator instead of QRandomGenerator::system() for their random
467 data needs.
468
469 For ease of use, QRandomGenerator provides a global object that can
470 be easily used, as in the following example:
471
472 \snippet code/src_corelib_global_qrandom.cpp 2
473
474 \section1 System-wide random number generator
475
476 QRandomGenerator::system() may be used to access the system-wide random
477 number generator, which is cryptographically-safe on all systems that Qt
478 runs on. This function will use hardware facilities to generate random
479 numbers where available. On such systems, those facilities are true Random
480 Number Generators. However, if they are true RNGs, those facilities have
481 finite entropy sources and thus may fail to produce any results if their
482 entropy pool is exhausted.
483
484 If that happens, first the operating system then QRandomGenerator will fall
485 back to Pseudo Random Number Generators of decreasing qualities (Qt's
486 fallback generator being the simplest). Whether those generators are still
487 of cryptographic quality is implementation-defined. Therefore,
488 QRandomGenerator::system() should not be used for high-frequency random
489 number generation, lest the entropy pool become empty. As a rule of thumb,
490 this class should not be called upon to generate more than a kilobyte per
491 second of random data (note: this may vary from system to system).
492
493 If an application needs true RNG data in bulk, it should use the operating
494 system facilities (such as \c{/dev/random} on Linux) directly and wait for
495 entropy to become available. If the application requires PRNG engines of
496 cryptographic quality but not of true randomness,
497 QRandomGenerator::system() may still be used (see section below).
498
499 If neither a true RNG nor a cryptographically secure PRNG are required,
500 applications should instead use PRNG engines like QRandomGenerator's
501 deterministic mode and those from the C++ Standard Library.
502 QRandomGenerator::system() can be used to seed those.
503
504 \section2 Fallback quality
505
506 QRandomGenerator::system() uses the operating system facilities to obtain
507 random numbers, which attempt to collect real entropy from the surrounding
508 environment to produce true random numbers. However, it's possible that the
509 entropy pool becomes exhausted, in which case the operating system will
510 fall back to a pseudo-random engine for a time. Under no circumstances will
511 QRandomGenerator::system() block, waiting for more entropy to be collected.
512
513 The following operating systems guarantee that the results from their
514 random-generation API will be of at least cryptographically-safe quality,
515 even if the entropy pool is exhausted: Apple OSes (Darwin), BSDs, Linux,
516 Windows. Barring a system installation problem (such as \c{/dev/urandom}
517 not being readable by the current process), QRandomGenerator::system() will
518 therefore have the same guarantees.
519
520 On other operating systems, QRandomGenerator will fall back to a PRNG of
521 good numeric distribution, but it cannot guarantee proper seeding in all
522 cases. Please consult the OS documentation for more information.
523
524 Applications that require QRandomGenerator not to fall back to
525 non-cryptographic quality generators are advised to check their operating
526 system documentation or restrict their deployment to one of the above.
527
528 \section1 Reentrancy and thread-safety
529
530 QRandomGenerator is reentrant, meaning that multiple threads can operate on
531 this class at the same time, so long as they operate on different objects.
532 If multiple threads need to share one PRNG sequence, external locking by a
533 mutex is required.
534
535 The exceptions are the objects returned by QRandomGenerator::global() and
536 QRandomGenerator::system(): those objects are thread-safe and may be used
537 by any thread without external locking. Note that thread-safety does not
538 extend to copying those objects: they should always be used by reference.
539
540 \section1 Standard C++ Library compatibility
541
542 QRandomGenerator is modeled after the requirements for random number
543 engines in the C++ Standard Library and may be used in almost all contexts
544 that the Standard Library engines can. Exceptions to the requirements are
545 the following:
546
547 \list
548 \li QRandomGenerator does not support seeding from another seed
549 sequence-like class besides std::seed_seq itself;
550 \li QRandomGenerator is not comparable (but is copyable) or
551 streamable to \c{std::ostream} or from \c{std::istream}.
552 \endlist
553
554 QRandomGenerator is also compatible with the uniform distribution classes
555 \c{std::uniform_int_distribution} and \c{std:uniform_real_distribution}, as
556 well as the free function \c{std::generate_canonical}. For example, the
557 following code may be used to generate a floating-point number in the range
558 [1, 2.5):
559
560 \snippet code/src_corelib_global_qrandom.cpp 3
561
562 \sa QRandomGenerator64
563 */
564
565/*!
566 \enum QRandomGenerator::System
567 \internal
568*/
569
570/*!
571 \fn QRandomGenerator::QRandomGenerator(quint32 seedValue)
572
573 Initializes this QRandomGenerator object with the value \a seedValue as
574 the seed. Two objects constructed or reseeded with the same seed value will
575 produce the same number sequence.
576
577 \sa seed(), securelySeeded()
578 */
579
580/*!
581 \fn template <qsizetype N> QRandomGenerator::QRandomGenerator(const quint32 (&seedBuffer)[N])
582 \overload
583
584 Initializes this QRandomGenerator object with the values found in the
585 array \a seedBuffer as the seed. Two objects constructed or reseeded with
586 the same seed value will produce the same number sequence.
587
588 \sa seed(), securelySeeded()
589 */
590
591/*!
592 \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qsizetype len)
593 \overload
594
595 Initializes this QRandomGenerator object with \a len values found in
596 the array \a seedBuffer as the seed. Two objects constructed or reseeded
597 with the same seed value will produce the same number sequence.
598
599 This constructor is equivalent to:
600 \snippet code/src_corelib_global_qrandom.cpp 4
601
602 \sa seed(), securelySeeded()
603 */
604
605/*!
606 \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
607 \overload
608
609 Initializes this QRandomGenerator object with the values found in the range
610 from \a begin to \a end as the seed. Two objects constructed or reseeded
611 with the same seed value will produce the same number sequence.
612
613 This constructor is equivalent to:
614 \snippet code/src_corelib_global_qrandom.cpp 5
615
616 \sa seed(), securelySeeded()
617 */
618
619/*!
620 \fn QRandomGenerator::QRandomGenerator(std::seed_seq &sseq)
621 \overload
622
623 Initializes this QRandomGenerator object with the seed sequence \a
624 sseq as the seed. Two objects constructed or reseeded with the same seed
625 value will produce the same number sequence.
626
627 \sa seed(), securelySeeded()
628 */
629
630/*!
631 \fn QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
632
633 Creates a copy of the generator state in the \a other object. If \a other is
634 QRandomGenerator::system() or a copy of that, this object will also read
635 from the operating system random-generating facilities. In that case, the
636 sequences generated by the two objects will be different.
637
638 In all other cases, the new QRandomGenerator object will start at the same
639 position in the deterministic sequence as the \a other object was. Both
640 objects will generate the same sequence from this point on.
641
642 For that reason, it is not advisable to create a copy of
643 QRandomGenerator::global(). If one needs an exclusive deterministic
644 generator, consider instead using securelySeeded() to obtain a new object
645 that shares no relationship with the QRandomGenerator::global().
646 */
647
648/*!
649 \fn bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
650 \relates QRandomGenerator
651
652 Returns true if the two engines \a rng1 and \a rng2 are at the same
653 state or if they are both reading from the operating system facilities,
654 false otherwise.
655*/
656
657/*!
658 \fn bool QRandomGenerator::operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
659
660 Returns \c true if the two engines \a rng1 and \a rng2 are at
661 different states or if one of them is reading from the operating system
662 facilities and the other is not, \c false otherwise.
663*/
664
665/*!
666 \typedef QRandomGenerator::result_type
667
668 A typedef to the type that operator() returns. That is, quint32.
669
670 \sa operator()
671 */
672
673/*!
674 \fn result_type QRandomGenerator::operator()()
675
676 Generates a 32-bit random quantity and returns it.
677
678 \sa generate(), generate64()
679 */
680
681/*!
682 \fn quint32 QRandomGenerator::generate()
683
684 Generates a 32-bit random quantity and returns it.
685
686 \sa {QRandomGenerator::operator()}{operator()()}, generate64()
687 */
688
689/*!
690 \fn quint64 QRandomGenerator::generate64()
691
692 Generates a 64-bit random quantity and returns it.
693
694 \sa {QRandomGenerator::operator()}{operator()()}, generate()
695 */
696
697/*!
698 \fn result_type QRandomGenerator::min()
699
700 Returns the minimum value that QRandomGenerator may ever generate. That is, 0.
701
702 \sa max(), QRandomGenerator64::min()
703 */
704
705/*!
706 \fn result_type QRandomGenerator::max()
707
708 Returns the maximum value that QRandomGenerator may ever generate. That is,
709 \c {std::numeric_limits<result_type>::max()}.
710
711 \sa min(), QRandomGenerator64::max()
712 */
713
714/*!
715 \fn void QRandomGenerator::seed(quint32 seed)
716
717 Reseeds this object using the value \a seed as the seed.
718 */
719
720/*!
721 \fn void QRandomGenerator::seed(std::seed_seq &seed)
722 \overload
723
724 Reseeds this object using the seed sequence \a seed as the seed.
725 */
726
727/*!
728 \fn void QRandomGenerator::discard(unsigned long long z)
729
730 Discards the next \a z entries from the sequence. This method is equivalent
731 to calling generate() \a z times and discarding the result, as in:
732
733 \snippet code/src_corelib_global_qrandom.cpp 6
734*/
735
736/*!
737 \fn template <typename ForwardIterator> void QRandomGenerator::generate(ForwardIterator begin, ForwardIterator end)
738
739 Generates 32-bit quantities and stores them in the range between \a begin
740 and \a end. This function is equivalent to (and is implemented as):
741
742 \snippet code/src_corelib_global_qrandom.cpp 7
743
744 This function complies with the requirements for the function
745 \l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq/generate}{\c std::seed_seq::generate},
746 which requires unsigned 32-bit integer values.
747
748 Note that if the [begin, end) range refers to an area that can store more
749 than 32 bits per element, the elements will still be initialized with only
750 32 bits of data. Any other bits will be zero. To fill the range with 64 bit
751 quantities, one can write:
752
753 \snippet code/src_corelib_global_qrandom.cpp 8
754
755 If the range refers to contiguous memory (such as an array or the data from
756 a QList), the fillRange() function may be used too.
757
758 \sa fillRange()
759 */
760
761/*!
762 \fn void QRandomGenerator::generate(quint32 *begin, quint32 *end)
763 \overload
764 \internal
765
766 Same as the other overload, but more efficiently fills \a begin to \a end.
767 */
768
769/*!
770 \fn template <typename UInt, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt *buffer, qsizetype count)
771
772 Generates \a count 32- or 64-bit quantities (depending on the type \c UInt)
773 and stores them in the buffer pointed by \a buffer. This is the most
774 efficient way to obtain more than one quantity at a time, as it reduces the
775 number of calls into the Random Number Generator source.
776
777 For example, to fill a list of 16 entries with random values, one may
778 write:
779
780 \snippet code/src_corelib_global_qrandom.cpp 9
781
782 \sa generate()
783 */
784
785/*!
786 \fn template <typename UInt, size_t N, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt (&buffer)[N])
787
788 Generates \c N 32- or 64-bit quantities (depending on the type \c UInt) and
789 stores them in the \a buffer array. This is the most efficient way to
790 obtain more than one quantity at a time, as it reduces the number of calls
791 into the Random Number Generator source.
792
793 For example, to fill generate two 32-bit quantities, one may write:
794
795 \snippet code/src_corelib_global_qrandom.cpp 10
796
797 It would have also been possible to make one call to generate64() and then split
798 the two halves of the 64-bit value.
799
800 \sa generate()
801 */
802
803/*!
804 \fn qreal QRandomGenerator::generateDouble()
805
806 Generates one random qreal in the canonical range [0, 1) (that is,
807 inclusive of zero and exclusive of 1).
808
809 This function is equivalent to:
810 \snippet code/src_corelib_global_qrandom.cpp 11
811
812 The same may also be obtained by using
813 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution}{\c std::uniform_real_distribution}
814 with parameters 0 and 1.
815
816 \sa generate(), generate64(), bounded()
817 */
818
819/*!
820 \fn double QRandomGenerator::bounded(double highest)
821
822 Generates one random double in the range between 0 (inclusive) and \a
823 highest (exclusive). This function is equivalent to and is implemented as:
824
825 \snippet code/src_corelib_global_qrandom.cpp 12
826
827 If the \a highest parameter is negative, the result will be negative too;
828 if it is infinite or NaN, the result will be infinite or NaN too (that is,
829 not random).
830
831 \sa generateDouble(), bounded(quint64)
832 */
833
834/*!
835 \fn quint32 QRandomGenerator::bounded(quint32 highest)
836 \overload
837
838 Generates one random 32-bit quantity in the range between 0 (inclusive) and
839 \a highest (exclusive). The same result may also be obtained by using
840 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution}
841 with parameters 0 and \c{highest - 1}. That class can also be used to obtain
842 quantities larger than 32 bits; for 64 bits, the 64-bit bounded() overload
843 can be used too.
844
845 For example, to obtain a value between 0 and 255 (inclusive), one would write:
846
847 \snippet code/src_corelib_global_qrandom.cpp 13
848
849 Naturally, the same could also be obtained by masking the result of generate()
850 to only the lower 8 bits. Either solution is as efficient.
851
852 Note that this function cannot be used to obtain values in the full 32-bit
853 range of quint32. Instead, use generate().
854
855 \sa generate(), generate64(), generateDouble()
856 */
857
858/*!
859 \fn int QRandomGenerator::bounded(int highest)
860 \overload
861
862 Generates one random 32-bit quantity in the range between 0 (inclusive) and
863 \a highest (exclusive). \a highest must be positive.
864
865 Note that this function cannot be used to obtain values in the full 32-bit
866 range of int. Instead, use generate() and cast to int.
867
868 \sa generate(), generate64(), generateDouble()
869 */
870
871/*!
872 \fn quint64 QRandomGenerator::bounded(quint64 highest)
873 \overload
874
875 Generates one random 64-bit quantity in the range between 0 (inclusive) and
876 \a highest (exclusive). The same result may also be obtained by using
877 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution<quint64>}
878 with parameters 0 and \c{highest - 1}.
879
880 Note that this function cannot be used to obtain values in the full 64-bit
881 range of \c{quint64}. Instead, use generate64().
882
883 \note This function is implemented as a loop, which depends on the random
884 value obtained. On the long run, on average it should loop just under 2
885 times, but if the random generator is defective, this function may take
886 considerably longer to execute.
887
888 \sa generate(), generate64(), generateDouble()
889 */
890
891/*!
892 \fn qint64 QRandomGenerator::bounded(qint64 highest)
893 \overload
894
895 Generates one random 64-bit quantity in the range between 0 (inclusive) and
896 \a highest (exclusive). \a highest must be positive.
897
898 Note that this function cannot be used to obtain values in the full 64-bit
899 range of \c{qint64}. Instead, use generate64() and cast to qint64 or instead
900 use the unsigned version of this function.
901
902 \note This function is implemented as a loop, which depends on the random
903 value obtained. On the long run, on average it should loop just under 2
904 times, but if the random generator is defective, this function may take
905 considerably longer to execute.
906
907 \sa generate(), generate64(), generateDouble()
908 */
909
910/*!
911 \fn quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest)
912 \overload
913
914 Generates one random 32-bit quantity in the range between \a lowest
915 (inclusive) and \a highest (exclusive). The \a highest parameter must be
916 greater than \a lowest.
917
918 The same result may also be obtained by using
919 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution}
920 with parameters \a lowest and \c{\a highest - 1}. That class can also be used to
921 obtain quantities larger than 32 bits.
922
923 For example, to obtain a value between 1000 (incl.) and 2000 (excl.), one
924 would write:
925
926 \snippet code/src_corelib_global_qrandom.cpp 14
927
928 Note that this function cannot be used to obtain values in the full 32-bit
929 range of quint32. Instead, use generate().
930
931 \sa generate(), generate64(), generateDouble()
932 */
933
934/*!
935 \fn int QRandomGenerator::bounded(int lowest, int highest)
936 \overload
937
938 Generates one random 32-bit quantity in the range between \a lowest
939 (inclusive) and \a highest (exclusive), both of which may be negative, but
940 \a highest must be greater than \a lowest.
941
942 Note that this function cannot be used to obtain values in the full 32-bit
943 range of int. Instead, use generate() and cast to int.
944
945 \sa generate(), generate64(), generateDouble()
946 */
947
948/*!
949 \fn quint64 QRandomGenerator::bounded(quint64 lowest, quint64 highest)
950 \overload
951
952 Generates one random 64-bit quantity in the range between \a lowest
953 (inclusive) and \a highest (exclusive). The \a highest parameter must be
954 greater than \a lowest.
955
956 The same result may also be obtained by using
957 \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution<quint64>}
958 with parameters \a lowest and \c{\a highest - 1}.
959
960 Note that this function cannot be used to obtain values in the full 64-bit
961 range of \c{quint64}. Instead, use generate64().
962
963 \note This function is implemented as a loop, which depends on the random
964 value obtained. On the long run, on average it should loop just under 2
965 times, but if the random generator is defective, this function may take
966 considerably longer to execute.
967
968 \sa generate(), generate64(), generateDouble()
969 */
970
971/*!
972 \fn qint64 QRandomGenerator::bounded(qint64 lowest, qint64 highest)
973 \overload
974
975 Generates one random 64-bit quantity in the range between \a lowest
976 (inclusive) and \a highest (exclusive), both of which may be negative, but
977 \a highest must be greater than \a lowest.
978
979 Note that this function cannot be used to obtain values in the full 64-bit
980 range of \c{qint64}. Instead, use generate64() and cast to qint64.
981
982 \note This function is implemented as a loop, which depends on the random
983 value obtained. On the long run, on average it should loop just under 2
984 times, but if the random generator is defective, this function may take
985 considerably longer to execute.
986
987 \sa generate(), generate64(), generateDouble()
988 */
989
990/*!
991 \fn qint64 QRandomGenerator::bounded(int lowest, qint64 highest)
992 \fn qint64 QRandomGenerator::bounded(qint64 lowest, int highest)
993 \fn quint64 QRandomGenerator::bounded(unsigned lowest, quint64 highest)
994 \fn quint64 QRandomGenerator::bounded(quint64 lowest, unsigned highest)
995 \overload
996
997 This function exists to help with overload resolution when the types of the
998 parameters don't exactly match. They will promote the smaller type to the
999 type of the larger one and call the correct overload.
1000 */
1001
1002/*!
1003 \fn QRandomGenerator *QRandomGenerator::system()
1004 \threadsafe
1005
1006 Returns a pointer to a shared QRandomGenerator that always uses the
1007 facilities provided by the operating system to generate random numbers. The
1008 system facilities are considered to be cryptographically safe on at least
1009 the following operating systems: Apple OSes (Darwin), BSDs, Linux, Windows.
1010 That may also be the case on other operating systems.
1011
1012 They are also possibly backed by a true hardware random number generator.
1013 For that reason, the QRandomGenerator returned by this function should not
1014 be used for bulk data generation. Instead, use it to seed QRandomGenerator
1015 or a random engine from the <random> header.
1016
1017 The object returned by this function is thread-safe and may be used in any
1018 thread without locks. It may also be copied and the resulting
1019 QRandomGenerator will also access the operating system facilities, but they
1020 will not generate the same sequence.
1021
1022 \sa securelySeeded(), global()
1023*/
1024
1025/*!
1026 \fn QRandomGenerator *QRandomGenerator::global()
1027 \threadsafe
1028
1029 Returns a pointer to a shared QRandomGenerator that was seeded using
1030 securelySeeded(). This function should be used to create random data
1031 without the expensive creation of a securely-seeded QRandomGenerator
1032 for a specific use or storing the rather large QRandomGenerator object.
1033
1034 For example, the following creates a random RGB color:
1035
1036 \snippet code/src_corelib_global_qrandom.cpp 15
1037
1038 Accesses to this object are thread-safe and it may therefore be used in any
1039 thread without locks. The object may also be copied and the sequence
1040 produced by the copy will be the same as the shared object will produce.
1041 Note, however, that if there are other threads accessing the global object,
1042 those threads may obtain samples at unpredictable intervals.
1043
1044 \sa securelySeeded(), system()
1045*/
1046
1047/*!
1048 \fn QRandomGenerator QRandomGenerator::securelySeeded()
1049
1050 Returns a new QRandomGenerator object that was securely seeded with
1051 QRandomGenerator::system(). This function will obtain the ideal seed size
1052 for the algorithm that QRandomGenerator uses and is therefore the
1053 recommended way for creating a new QRandomGenerator object that will be
1054 kept for some time.
1055
1056 Given the amount of data required to securely seed the deterministic
1057 engine, this function is somewhat expensive and should not be used for
1058 short-term uses of QRandomGenerator (using it to generate fewer than 2600
1059 bytes of random data is effectively a waste of resources). If the use
1060 doesn't require that much data, consider using QRandomGenerator::global()
1061 and not storing a QRandomGenerator object instead.
1062
1063 \sa global(), system()
1064 */
1065
1066/*!
1067 \class QRandomGenerator64
1068 \inmodule QtCore
1069 \since 5.10
1070
1071 \brief The QRandomGenerator64 class allows one to obtain 64-bit random values
1072 from a high-quality, seed-less Random Number Generator.
1073
1074 QRandomGenerator64 is a simple adaptor class around QRandomGenerator, making the
1075 QRandomGenerator::generate64() function the default for operator()(), instead of the
1076 function that returns 32-bit quantities. This class is intended to be used
1077 in conjunction with Standard Library algorithms that need 64-bit quantities
1078 instead of 32-bit ones.
1079
1080 In all other aspects, the class is the same. Please refer to
1081 QRandomGenerator's documentation for more information.
1082
1083 \sa QRandomGenerator
1084*/
1085
1086/*!
1087 \typedef QRandomGenerator64::result_type
1088
1089 A typedef to the type that operator() returns. That is, quint64.
1090
1091 \sa operator()
1092 */
1093
1094/*!
1095 \fn quint64 QRandomGenerator64::generate()
1096
1097 Generates one 64-bit random value and returns it.
1098
1099 Note about casting to a signed integer: all bits returned by this function
1100 are random, so there's a 50% chance that the most significant bit will be
1101 set. If you wish to cast the returned value to qint64 and keep it positive,
1102 you should mask the sign bit off:
1103
1104 \snippet code/src_corelib_global_qrandom.cpp 16
1105
1106 \sa QRandomGenerator, QRandomGenerator::generate64()
1107 */
1108
1109/*!
1110 \fn result_type QRandomGenerator64::operator()()
1111
1112 Generates a 64-bit random quantity and returns it.
1113
1114 \sa QRandomGenerator::generate(), QRandomGenerator::generate64()
1115 */
1116
1117constexpr QRandomGenerator::Storage::Storage()
1118 : dummy(0)
1119{
1120 // nothing
1121}
1122
1123inline QRandomGenerator64::QRandomGenerator64(System s)
1124 : QRandomGenerator(s)
1125{
1126}
1127
1129{
1131 Q_ASSERT(self->type == SystemRNG);
1132 return self;
1133}
1134
1136{
1138
1139 // Yes, this is a double-checked lock.
1140 // We can return even if the type is not completely initialized yet:
1141 // any thread trying to actually use the contents of the random engine
1142 // will necessarily wait on the lock.
1143 if (Q_LIKELY(self->type != SystemRNG))
1144 return self;
1145
1147 if (self->type == SystemRNG)
1149
1150 return self;
1151}
1152
1154{
1155 QRandomGenerator64 result(System{});
1157 return result;
1158}
1159
1160/*!
1161 \internal
1162*/
1163inline QRandomGenerator::QRandomGenerator(System)
1164 : type(SystemRNG)
1165{
1166 // don't touch storage
1167}
1168
1169QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
1170 : type(other.type)
1171{
1172 Q_ASSERT(this != system());
1174
1175 if (type != SystemRNG) {
1177 storage.engine() = other.storage.engine();
1178 }
1179}
1180
1181QRandomGenerator &QRandomGenerator::operator=(const QRandomGenerator &other)
1182{
1183 if (Q_UNLIKELY(this == system()) || Q_UNLIKELY(this == SystemAndGlobalGenerators::globalNoInit()))
1184 qFatal("Attempted to overwrite a QRandomGenerator to system() or global().");
1185
1186 if ((type = other.type) != SystemRNG) {
1188 storage.engine() = other.storage.engine();
1189 }
1190 return *this;
1191}
1192
1193QRandomGenerator::QRandomGenerator(std::seed_seq &sseq) noexcept
1194 : type(MersenneTwister)
1195{
1196 Q_ASSERT(this != system());
1198
1199 new (&storage.engine()) RandomEngine(sseq);
1200}
1201
1202QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
1203 : type(MersenneTwister)
1204{
1205 Q_ASSERT(this != system());
1207
1208 std::seed_seq s(begin, end);
1209 new (&storage.engine()) RandomEngine(s);
1210}
1211
1212void QRandomGenerator::discard(unsigned long long z)
1213{
1214 if (Q_UNLIKELY(type == SystemRNG))
1215 return;
1216
1218 storage.engine().discard(z);
1219}
1220
1221bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
1222{
1223 if (rng1.type != rng2.type)
1224 return false;
1225 if (rng1.type == SystemRNG)
1226 return true;
1227
1228 // Lock global() if either is it (otherwise this locking is a no-op)
1229 using PRNGLocker = QRandomGenerator::SystemAndGlobalGenerators::PRNGLocker;
1230 PRNGLocker locker(&rng1 == QRandomGenerator::global() ? &rng1 : &rng2);
1231 return rng1.storage.engine() == rng2.storage.engine();
1232}
1233
1234/*!
1235 \internal
1236
1237 Fills the range pointed by \a buffer with \a count 32-bit random values.
1238 The buffer must be correctly aligned.
1239
1240 Returns the value of the first two 32-bit entries as a \c{quint64}.
1241 */
1242quint64 QRandomGenerator::_fillRange(void *buffer, qptrdiff count)
1243{
1244 // Verify that the pointers are properly aligned for 32-bit
1245 Q_ASSERT(quintptr(buffer) % sizeof(quint32) == 0);
1246 Q_ASSERT(count >= 0);
1247 Q_ASSERT(buffer || count <= 2);
1248
1249 quint64 dummy;
1250 quint32 *begin = static_cast<quint32 *>(buffer ? buffer : &dummy);
1251 quint32 *end = begin + count;
1252
1253 if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & (UseSystemRNG|SetRandomData))) {
1254 SystemGenerator::self().generate(begin, end);
1255 } else {
1257 std::generate(begin, end, [this]() { return storage.engine()(); });
1258 }
1259
1260 if (end - begin == 1)
1261 return *begin;
1262 return begin[0] | (quint64(begin[1]) << 32);
1263}
1264
1265// helper function to call fillBuffer, since we need something to be
1266// argument-dependent
1267template <typename Generator, typename FillBufferType, typename T>
1268static qsizetype callFillBuffer(FillBufferType f, T *v)
1269{
1270 if constexpr (std::is_member_function_pointer_v<FillBufferType>) {
1271 // member function, need an object
1272 return (Generator::self().*f)(v, sizeof(*v));
1273 } else {
1274 // static, call directly
1275 return f(v, sizeof(*v));
1276 }
1277}
1278
1279/*!
1280 \internal
1281
1282 Returns an initial random value (useful for QHash's global seed). This
1283 function attempts to use OS-provided random values to avoid initializing
1284 QRandomGenerator::system() and qsimd.cpp.
1285
1286 Note: on some systems, this functionn may rerturn the same value every time
1287 it is called.
1288 */
1289QRandomGenerator::InitialRandomData qt_initial_random_value() noexcept
1290{
1291#if QT_CONFIG(getauxval) && defined(AT_RANDOM)
1292 auto at_random_ptr = reinterpret_cast<size_t *>(getauxval(AT_RANDOM));
1293 if (at_random_ptr)
1294 return qFromUnaligned<QRandomGenerator::InitialRandomData>(at_random_ptr);
1295#endif
1296
1297 // bypass the hardware RNG, which would mean initializing qsimd.cpp
1298
1299 QRandomGenerator::InitialRandomData v;
1300 for (int attempts = 16; attempts; --attempts) {
1301 using Generator = QRandomGenerator::SystemGenerator;
1302 auto fillBuffer = &Generator::fillBuffer;
1303 if (callFillBuffer<Generator>(fillBuffer, &v) != sizeof(v))
1304 continue;
1305
1306 return v;
1307 }
1308
1309 quint32 data[sizeof(v) / sizeof(quint32)];
1310 fallback_fill(data, std::size(data));
1311 memcpy(v.data, data, sizeof(v.data));
1312 return v;
1313}
1314
1315QT_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:1268
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:1221
#define Q_ASSERT(cond)
Definition qrandom.cpp:48
QRandomGenerator::InitialRandomData qt_initial_random_value() noexcept
Definition qrandom.cpp:1289
@ MersenneTwister
Definition qrandom_p.h:36
@ SystemRNG
Definition qrandom_p.h:35
@ UseSystemRNG
Definition qrandom_p.h:25
@ SkipSystemRNG
Definition qrandom_p.h:26
@ SetRandomData
Definition qrandom_p.h:28
@ SkipHWRNG
Definition qrandom_p.h:27
@ RandomDataMask
Definition qrandom_p.h:31
static QRandomGenerator64 * system()
Definition qrandom.cpp:353
static void securelySeed(QRandomGenerator *rng)
Definition qrandom.cpp:370
static SystemAndGlobalGenerators * self()
Definition qrandom.cpp:346
static QRandomGenerator64 * globalNoInit()
Definition qrandom.cpp:362
uchar data[sizeof(QRandomGenerator64)]
Definition qrandom.cpp:330
void generate(quint32 *begin, quint32 *end) noexcept(FillBufferNoexcept)
Definition qrandom.cpp:283
static SystemGenerator & self()
Definition qrandom.cpp:397
void generate(T *begin, T *end)
Definition qrandom.cpp:153