QRandomGenerator 类
QRandomGenerator 类允许从高质量的随机数生成器获取随机值。 更多...
头文件 | #include <QRandomGenerator> |
CMake | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake | QT += core |
继承自 |
注意:本类中的所有函数都是 可重入的。
注意:这些函数也是 线程安全的
公共类型
公共函数
QRandomGenerator(quint32 seedValue = 1) | |
QRandomGenerator(const quint32 (&)[N] seedBuffer) | |
QRandomGenerator(const quint32 *seedBuffer, qsizetype len) | |
QRandomGenerator(std::seed_seq &sseq) | |
QRandomGenerator(const quint32 *begin, const quint32 *end) | |
QRandomGenerator(const QRandomGenerator &other) | |
double | bounded(double highest) |
quint32 | bounded(quint32 highest) |
quint32 | bounded(quint32 lowest, quint32 highest) |
int | bounded(int highest) |
int | bounded(int lowest, int highest) |
quint64 | bounded(quint64 highest) |
quint64 | bounded(quint64 lowest, quint64 highest) |
qint64 | bounded(qint64 highest) |
qint64 | bounded(qint64 lowest, qint64 highest) |
qint64 | bounded(int lowest, qint64 highest) |
qint64 | bounded(qint64 lowest, int highest) |
quint64 | bounded(unsigned int lowest, quint64 highest) |
quint64 | bounded(quint64 lowest, unsigned int highest) |
void | discard(unsigned long long z) |
void | fillRange(UInt *buffer, qsizetype count) |
void | fillRange(UInt (&)[N] buffer) |
quint64 | generate64() |
quint32 | generate() |
void | 生成(ForwardIterator begin, ForwardIterator end) |
double | 生成Double() |
void | 种子(quint32 seed = 1) |
void | 种子(std::seed_seq &seed) |
QRandomGenerator::result_type | operator()() |
静态公共成员
QRandomGenerator * | 全局() |
QRandomGenerator::result_type | 最大() |
QRandomGenerator::result_type | 最小() |
QRandomGenerator | 安全种子() |
QRandomGenerator * | 系统() |
相关非成员
bool | 不等(const QRandomGenerator &rng1, const QRandomGenerator &rng2) |
详细描述
QRandomGenerator 可以用于从一个高质量随机数生成器中生成随机值。与 C++ 随机引擎类似,QRandomGenerator 可以通过构造函数使用用户提供的数据进行初始化。当初始化后,此类生成的数字序列是确定的。也就是说,给定相同的种子数据,QRandomGenerator 将生成相同的数字序列。但是,给定不同的种子,结果将相当不同。
QRandomGenerator::securelySeeded() 可以用于创建一个用 QRandomGenerator::system() securely 种子的 QRandomGenerator,这意味着它生成的数字序列不容易预测。此外,QRandomGenerator::global() 返回一个全局的 QRandomGenerator 实例,Qt 将确保该实例是安全种子的。此对象是线程安全的,大多数情况下可以共享,且始终从 QRandomGenerator::system() 种子。
QRandomGenerator::system() 可以用于访问系统的密码学安全随机生成器。在 Unix 系统上,它相当于从 /dev/urandom
或 getrandom()
或 getentropy()
系统调用读取。
该类可以生成32位或64位数,或者填充相应大小的数组。生成新值的最常见方法是调用 generate(),generate64() 或 fillRange() 函数。使用方法如下:
quint32 value = QRandomGenerator::global()->generate();
此外,它还提供了一个浮点函数 generateDouble(),它返回一个在 [0, 1) 范围内的数(即包括0,不包括1)。还有一组方便的函数,这些函数可以方便地获取一个在有限整数范围内的随机数。
种子和确定性
QRandomGenerator 可以用特定的种子数据初始化。当这样做时,由此对象生成的数字将始终相同,如下例所示:
QRandomGenerator prng1(1234), prng2(1234); Q_ASSERT(prng1.generate() == prng2.generate()); Q_ASSERT(prng1.generate64() == prng2.generate64());
种子数据的形式是一个或多个32位单词。理想的种子大小约为 QRandomGenerator 类本身的大小。由于种子数据的混合,QRandomGenerator 不能保证不同的种子会产生不同的序列。
QRandomGenerator::global(),与所有由 QRandomGenerator::securelySeeded() 创建的生成器一样,始终从 QRandomGenerator::system() 种子,因此无法使其产生相同的序列。
大批量数据
在确定性模式下操作时,QRandomGenerator 可用于大批量数据生成。事实上,不需要密码学安全或真正随机数据的应用程序建议使用普通的 QRandomGenerator 而不是 QRandomGenerator::system() 来满足它们的随机数据需求。
为了便于使用,QRandomGenerator提供了全局对象,可以轻松使用,如下面的示例所示
int x = QRandomGenerator::global()->generate(); int y = QRandomGenerator::global()->generate(); int w = QRandomGenerator::global()->bounded(16384); int h = QRandomGenerator::global()->bounded(16384);
系统级随机数生成器
QRandomGenerator::system() 可以用来访问系统级的随机数生成器,这对于所有运行Qt的系统都是密码安全的。此函数将在硬件设施可用时使用它来生成随机数。在这样系统中,这些设施是真正的随机数生成器。然而,如果它们是真正的RNG,这些设施有有限的熵源,因此当它们的熵池耗尽时,可能无法产生任何结果。
如果发生这种情况,首先操作系统然后QRandomGenerator将回退到质量递减的伪随机数生成器(Qt的回退生成器是最简单的)。这些生成器是否仍然有密码学质量是未定义的。因此,QRandomGenerator::system()不应该用于高频随机数生成,以免熵池耗尽。一般来说,这个类不应被用来生成超过每秒1千字节随机数据(注意:这会因系统而异)。
如果一个应用需要大量真正的RNG数据,它应直接使用操作系统设施(例如Linux上的/dev/random
)并等待熵变得可用。如果一个应用需要密码学质量的伪随机数生成器而不是真正的随机性,QRandomGenerator::system()仍然可以用来(见下面的章节)。
如果不需要真正的RNG或密码学安全的伪随机数生成器,则应用应使用类似QRandomGenerator的确定性模式的PRNG引擎和C++标准库中的那些。可以使用QRandomGenerator::system()来初始化它们。
回退质量
QRandomGenerator::system()使用操作系统设施来获取随机数,它试图从周围环境中收集实际熵以产生真正的随机数。然而,有可能熵池耗尽,这时操作系统将暂时回退到伪随机引擎。在任何情况下,QRandomGenerator::system()都不会阻塞,等待收集更多熵。
以下操作系统保证了即使熵池耗尽,其随机生成API的结果至少达到密码学安全质量:Apple OS们(Darwin)、BSDs、Linux、Windows。除非系统安装存在问题(例如/dev/urandom
不能由当前进程读取),否则QRandomGenerator::system()将保证相同。
在其它操作系统上,QRandomGenerator将回退到一个好的数值分布的伪随机数生成器,但无法保证所有情况下都正确的初始化。请参考操作系统文档以获取更多信息。
建议需要QRandomGenerator不要回退到非密码学质量生成器的应用检查其操作系统文档或将其部署限制在上面的其中之一。
可重入性和线程安全
QRandomGenerator是可重入的,这意味着多个线程可以同时在这个类上操作,只要它们操作不同的对象。如果多个线程需要共享一个伪随机数生成器序列,则需要外部由互斥锁来进行加锁。
异常包括由 QRandomGenerator::global() 和 QRandomGenerator::system() 返回的对象:这些对象是线程安全的,可以被任何线程使用而不需要外部锁定。请注意,线程安全不包括复制这些对象:应始终通过引用使用它们。
C++标准库兼容性
QRandomGenerator遵从C++标准库中对随机数发生器的要求,并可以在几乎与标准库引擎相同的环境中使用。以下是一些例外:
- QRandomGenerator不支持从除了std::seed_seq本身之外的其他类中获取播种,
- QRandomGenerator不能与std::ostream比较(但可以复制)或从std::istream读取。
QRandomGenerator也与均匀分布类std::uniform_int_distribution
和std::uniform_real_distribution
,以及免费函数std::generate_canonical
兼容。例如,以下代码可以用来生成一个[1, 2.5)范围内的浮点数:
std::uniform_real_distribution dist(1, 2.5); return dist(*QRandomGenerator::global());
另请参阅QRandomGenerator64。
成员函数文档
qint64 QRandomGenerator::bounded(int lowest, qint64 highest)
qint64 QRandomGenerator::bounded(qint64 lowest, int highest)
quint64 QRandomGenerator::bounded(quint64 lowest, unsigned int highest)
quint64 QRandomGenerator::bounded(unsigned int lowest, quint64 highest)
这是一个重载函数。
此函数存在是为了帮助处理参数类型不精确匹配时的重载解析。它们会将较小的类型提升为较大的类型,并调用正确重载。
QRandomGenerator::QRandomGenerator(quint32 seedValue = 1)
使用seedValue作为种子值初始化此QRandomGenerator对象。使用相同种子值构建或重新播种的两个对象将生成相同的数字序列。
另请参阅seed()和securelySeeded。
template <qsizetype N> QRandomGenerator::QRandomGenerator(const quint32 (&)[N] seedBuffer)
这是一个重载函数。
使用数组seedBuffer中找到的值作为种子值初始化此QRandomGenerator对象。使用相同种子值构建或重新播种的两个对象将生成相同的数字序列。
另请参阅seed()和securelySeeded。
QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qsizetype len)
这是一个重载函数。
使用数组seedBuffer中找到的len个值初始化此QRandomGenerator对象作为种子。使用相同种子值构建或重生成的两个对象将产生相同数字序列。
此构造函数等同于
std::seed_seq sseq(seedBuffer, seedBuffer + len); QRandomGenerator generator(sseq);
另请参阅seed()和securelySeeded。
[noexcept]
QRandomGenerator::QRandomGenerator(std::seed_seq &sseq)
这是一个重载函数。
使用种子序列sseq初始化此QRandomGenerator对象作为种子。使用相同种子值构建或重生成的两个对象将产生相同数字序列。
另请参阅seed()和securelySeeded。
QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
这是一个重载函数。
使用介于begin和end之间的值初始化此QRandomGenerator对象作为种子。使用相同种子值构建或重生成的两个对象将产生相同数字序列。
此构造函数等同于
std::seed_seq sseq(begin, end); QRandomGenerator generator(sseq);
另请参阅seed()和securelySeeded。
QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
在other对象中创建发电机状态的副本。如果other是QRandomGenerator::system()或其副本,则此对象也将从操作系统的随机生成设施中读取。在这种情况下,两个对象生成的序列将不同。
在其他所有情况下,新的QRandomGenerator对象将开始与other对象相同的确定序列位置。从这一点开始,两个对象将生成相同的序列。
因此,不建议创建QRandomGenerator::global的副本。如果需要专属的确定性生成器,可以考虑改用securelySeeded()来获取与QRandomGenerator::global没有关联的新对象。
double QRandomGenerator::bounded(double highest)
生成一个介于0(包含)和highest(不包含)之间的随机double。此函数等同于并作为
return generateDouble() * highest;
如果highest参数为负,则结果也将是负的;如果是无穷大或NaN,则结果也将是无穷大或NaN(即非随机)。
另请参阅 generateDouble() 和 bounded()。
quint32 QRandomGenerator::bounded(quint32 highest)
这是一个重载函数。
生成一个介于0(包含)和highest(不包含)之间的随机32位整数。还可以通过使用带参数0和highest - 1
的std::uniform_int_distribution
来获得相同的结果。此类还可以用于获取大于32位的数量;对于64位,也可以使用64位的bounded()重载。
例如,要获取介于0和255(包含)之间的值,可以编写
quint32 v = QRandomGenerator::global()->bounded(256);
当然,也可以通过仅屏蔽generate()的结果,只保留最低8位来获得相同的结果。两种解决方案都具有同样的效率。
请注意,此函数不能用于获取 quint32 的完整 32 位范围中的值。相反,请使用 generate。
另请参阅generate,generate64 和 generateDouble。
quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest)
这是一个重载函数。
生成一个介于 lowest(包含)和 highest(不包含)之间的随机 32 位数。参数 highest 必须大于 lowest。
也可以通过使用具有参数 lowest 和 \a highest - 1
的 std::uniform_int_distribution
获取相同的结果。该类还可以用于获取大于 32 位的数量。
例如,为了获取介于 1000(包含)和 2000(不包含)之间的值,可以这样编写
quint32 v = QRandomGenerator::global()->bounded(1000, 2000);
请注意,此函数不能用于获取 quint32 的完整 32 位范围中的值。相反,请使用 generate。
另请参阅generate,generate64 和 generateDouble。
int QRandomGenerator::bounded(int highest)
这是一个重载函数。
生成一个介于 0(包含)和 highest(不包含)之间的随机 32 位数。参数 highest 必须是正数。
请注意,此函数不能用于获取 int 的完整 32 位范围中的值。相反,请使用 generate 并将其转换为 int。
另请参阅generate,generate64 和 generateDouble。
int QRandomGenerator::bounded(int lowest, int highest)
这是一个重载函数。
生成一个介于 lowest(包含)和 highest(不包含)之间的随机 32 位数,两个参数都可能是负数,但 highest 必须大于 lowest。
请注意,此函数不能用于获取 int 的完整 32 位范围中的值。相反,请使用 generate 并将其转换为 int。
另请参阅generate,generate64 和 generateDouble。
quint64 QRandomGenerator::bounded(quint64 highest)
这是一个重载函数。
生成一个介于 0(包含)和 highest(不包含)之间的随机 64 位数。也可以通过使用具有参数 0 和 highest - 1
的 std::uniform_int_distribution<quint64>
获取相同的结果。
请注意,此函数不能用于获取 quint64 的完整 64 位范围中的值。相反,请使用 generate64。
注意:此函数作为循环实现,依赖于获得的随机值。从长远来看,平均每次循环略低于 2 次,但如果随机数生成器有缺陷,此函数的执行时间可能会显著更长。
另请参阅generate,generate64 和 generateDouble。
quint64 QRandomGenerator::bounded(quint64 lowest, quint64 highest)
这是一个重载函数。
生成一个介于 lowest(包含)和 highest(不包含)之间的随机 64 位数。参数 highest 必须大于 lowest。
也可以通过使用具有参数 lowest 和 \a highest - 1
的 std::uniform_int_distribution<quint64>
获取相同的结果。
请注意,此函数不能用于获取 quint64 的完整 64 位范围中的值。相反,请使用 generate64。
注意:此函数作为循环实现,依赖于获得的随机值。从长远来看,平均每次循环略低于 2 次,但如果随机数生成器有缺陷,此函数的执行时间可能会显著更长。
另请参阅generate,generate64 和 generateDouble。
qint64 QRandomGenerator::bounded(qint64 最高值)
这是一个重载函数。
生成一个介于0(包含)和最高值(不包含)之间的随机64位数值。 最高值必须是正数。
请注意,此函数不能用于获取64位qint64的全范围值。请使用generate64()并将结果转换为qint64,或者使用该函数的无符号版本。
注意:此函数作为循环实现,依赖于获得的随机值。从长远来看,平均每次循环略低于 2 次,但如果随机数生成器有缺陷,此函数的执行时间可能会显著更长。
另请参阅generate,generate64 和 generateDouble。
qint64 QRandomGenerator::bounded(qint64 最低值, qint64 最高值)
这是一个重载函数。
生成一个介于最低值(包含)和最高值(不包含)之间的随机64位数值,这两个值都可能为负数,但最高值必须大于最低值。
请注意,此函数不能用于获取64位qint64的全范围值。请使用generate64()并将结果转换为qint64。
注意:此函数作为循环实现,依赖于获得的随机值。从长远来看,平均每次循环略低于 2 次,但如果随机数生成器有缺陷,此函数的执行时间可能会显著更长。
另请参阅generate,generate64 和 generateDouble。
void QRandomGenerator::discard(unsigned long long z)
丢弃序列中的下一个z个条目。此方法等同于调用generate() z次并丢弃结果,如下所示
while (z--) generator.generate();
template <typename UInt, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt *缓冲区, qsizetype 计数)
生成计数个32位或64位(根据数据类型UInt
)数值,并将它们存储在由缓冲区指向的位置。这是同时获取多个数值的最有效方法,因为它减少了进入随机数生成源调用的次数。
例如,要使用随机值填充具有16个条目的列表,可以编写
QList<quint32> list; list.resize(16); QRandomGenerator::global()->fillRange(list.data(), list.size());
另请参阅 generate。
template <typename UInt, size_t N, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt (&)[N] 缓冲区)
生成N
个32位或64位(根据数据类型UInt
)数值,并将它们存储在缓冲区数组中。这是同时获取多个数值的最有效方法,因为它减少了进入随机数生成源调用的次数。
例如,要生成两个32位数值,可以编写
quint32 array[2]; QRandomGenerator::global()->fillRange(array);
也可以通过调用generate64()并分割64位值的两个半部分来完成一个调用。
另请参阅 generate。
quint64 QRandomGenerator::generate64()
生成一个64位随机数值并返回它。
另请参阅 operator()() 和 generate。
quint32 QRandomGenerator::generate()
生成一个32位随机数值并返回它。
另请参阅 operator()() 和 generate64。
模板 <typename ForwardIterator> void QRandomGenerator::generate(ForwardIterator begin, ForwardIterator end)
生成32位整数并存储在begin和end之间的范围内。此函数等同于(也以这种方式实现)
std::generate(begin, end, [this]() { return generate(); });
该函数符合std::seed_seq::generate
函数的要求,该函数需要无符号32位整数值。
注意,如果[i, end)范围指的是可以存储单元素超过32位的空间,元素仍将只使用32位数据初始化。其他位都将为零。要填充范围为64位整数,可以这样写
std::generate(begin, end, []() { return QRandomGenerator::global()->generate64(); });
如果该范围指的是连续的内存(如数组或QList中的数据),也可以使用fillRange()函数。
另请参阅fillRange。
double QRandomGenerator::generateDouble()
生成一个在规范范围[0, 1)内的qreal随机数(即,包含0但不包括1)。
此函数等同于
QRandomGenerator64 rd; return std::generate_canonical<qreal, std::numeric_limits<qreal>::digits>(rd);
也可以通过使用std::uniform_real_distribution
并设置参数为0和1来得到同样的结果。
另请参阅generate()、generate64()和bounded()。
[静态]
QRandomGenerator *QRandomGenerator::global()
返回一个使用securelySeeded修复过的共享QRandomGenerator指针。这个函数应该用来创建随机数据,而不需要为特定的用途创建一个昂贵的QRandomGenerator或存储一个相当大的QRandomGenerator对象。
例如,以下创建了一个随机的RGB颜色
return QColor::fromRgb(QRandomGenerator::global()->generate());
对这个对象的访问是线程安全的,因此可以在任何一个线程中使用它而无需加锁。该对象也可以被复制,复制的顺序将和共享对象产生的顺序相同。但是请注意,如果有其他线程正在访问全局对象,那些线程可能会以不可预测的时间间隔获得样本。
注意:此函数是线程安全的。
另请参阅securelySeeded()和system()。
[静态常量表达式]
QRandomGenerator::result_type QRandomGenerator::max()
返回QRandomGenerator可能生成的最大值。即,std::numeric_limits<result_type>::max()
。
另请参阅min()和QRandomGenerator64::max()。
[静态常量表达式]
QRandomGenerator::result_type QRandomGenerator::min()
返回QRandomGenerator可能生成的最小值。即,0。
另请参阅 max() 和 QRandomGenerator64::min()。
[静态]
QRandomGenerator QRandomGenerator::securelySeeded()
返回一个新的 QRandomGenerator 对象,它使用 QRandomGenerator::system()() 加密种子。此函数将获取 QRandomGenerator 所使用的算法的理想种子大小,因此是创建一个将保持一段时间的 QRandomGenerator 对象的推荐方法。
由于需要的安全种子数据量,此函数有点昂贵,并且不应用于 QRandomGenerator 的短期使用(用它生成少于2600字节的随机数据实际上是资源的浪费)。如果不需要那么多数据,请考虑使用 QRandomGenerator::global() 并且不存储 QRandomGenerator 对象。
void QRandomGenerator::seed(quint32 seed = 1)
使用值 seed 作为种子重新为该对象设置种子。
[noexcept]
void QRandomGenerator::seed(std::seed_seq &seed)
这是一个重载函数。
使用种子序列 seed 作为种子重新为该对象设置种子。
[static]
QRandomGenerator *QRandomGenerator::system()
返回指向一个共享的 QRandomGenerator 的指针,它始终使用操作系统提供的设施来生成随机数。在以下操作系统上,系统设施被认为至少是密码学安全的:Apple OSes (Darwin)、BSDs、Linux、Windows。在其他操作系统上也可能是这种情况。
它们也可能由真正的硬件随机数生成器支持。因此,此函数返回的 QRandomGenerator 不应用于生成大量数据。相反,应将其用于为 QRandomGenerator 或来自 `
此函数返回的对象是线程安全的,可以在任何线程中使用而无需加锁。它还可以被复制,复制后的 QRandomGenerator 也会访问操作系统设施,但将不会生成相同的序列。
注意:此函数是线程安全的。
另请参阅 securelySeeded() 和 global。
QRandomGenerator::result_type QRandomGenerator::operator()()
生成一个32位随机数值并返回它。
另请参阅 generate() 和 generate64。
相关非成员函数
bool operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
如果两个引擎 rng1 和 rng2 处于不同的状态,或者其中一个从操作系统设施中读取,而另一个不是,则返回 true
;否则返回 false
。
© 2024 Qt公司有限公司。本文件中包含的文档贡献的版权属于各自的所有者。提供的文档遵循免费软件基金会发布的GNU自由文档许可协议版本1.3的条款。Qt及其相关标志是芬兰及/或其他国家和地区的Qt公司有限公司的商标。所有其他商标均为其各自所有者的财产。