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