QRandomGenerator Class

QRandomGenerator 类允许从高质量随机数生成器中获取随机值。更多

头文件: #include <QRandomGenerator>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
继承于

QRandomGenerator64

注意:该类中的所有函数都是可重入的

注:这些函数也是线程安全的

公共类型

公共函数

QRandomGenerator(quint32 seedValue = 1)
QRandomGenerator(const quint32 (&)[N] seedBuffer)
QRandomGenerator(std::seed_seq &sseq)
QRandomGenerator(const quint32 *begin, const quint32 *end)
QRandomGenerator(const quint32 *seedBuffer, qsizetype len)
QRandomGenerator(const QRandomGenerator &other)
double bounded(double highest)
int bounded(int highest)
qint64 bounded(qint64 highest)
quint32 bounded(quint32 highest)
quint64 bounded(quint64 highest)
int bounded(int lowest, int highest)
qint64 bounded(int lowest, qint64 highest)
qint64 bounded(qint64 lowest, int highest)
qint64 bounded(qint64 lowest, qint64 highest)
quint32 bounded(quint32 lowest, quint32 highest)
quint64 bounded(quint64 lowest, quint64 highest)
quint64 bounded(quint64 lowest, unsigned int highest)
quint64 bounded(unsigned int lowest, quint64 highest)
void discard(unsigned long long z)
void fillRange(UInt (&)[N] buffer)
void fillRange(UInt *buffer, qsizetype count)
quint64 generate64()
quint32 generate()
void generate(ForwardIterator begin, ForwardIterator end)
double generateDouble()
void seed(quint32 seed = 1)
void seed(std::seed_seq &seed)
QRandomGenerator::result_type operator()()

静态公共成员

QRandomGenerator *global()
QRandomGenerator::result_type max()
QRandomGenerator::result_type min()
QRandomGenerator securelySeeded()
QRandomGenerator *system()
bool operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2)

详细说明

QRandomGenerator 可用于从高质量随机数生成器中生成随机值。与 C++ 随机引擎一样,QRandomGenerator 可通过构造函数使用用户提供的值作为种子。播种后,该类生成的数字序列是确定的。也就是说,给定相同的种子数据,QRandomGenerator 将生成相同的数字序列。但如果给定不同的种子数据,生成的结果就会大不相同。

QRandomGenerator::securelySeeded(QRandomGenerator::system() 可以用来创建一个安全种子的 QRandomGenerator,这意味着它生成的数字序列不容易预测。此外,QRandomGenerator::global() 还会返回一个 QRandomGenerator 的全局实例,Qt XML 将确保对该实例进行安全播种。该对象是线程安全的,可在大多数情况下共享使用,并始终从QRandomGenerator::system() 进行播种。

QRandomGenerator::system() 可用于访问系统的加密安全随机生成器。在 Unix 系统中,它相当于从/dev/urandomgetrandom()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() 不适用于高频随机数生成,以免熵池变空。根据经验,调用该类生成的随机数据不应超过每秒一千字节(注意:这可能因系统而异)。

如果应用程序需要大量真正的 RNG 数据,则应直接使用操作系统设施(如 Linux 上的/dev/random ),并等待熵可用。如果应用程序需要具有加密质量的 PRNG 引擎,但不需要真正的随机性,则仍可使用QRandomGenerator::system() (见下文)。

如果既不需要真正的 RNG,也不需要加密安全的 PRNG,应用程序就应该使用 PRNG 引擎,如 QRandomGenerator 的确定性模式和 C++ 标准库中的 PRNG 引擎。QRandomGenerator::system() 可用于为这些引擎播种。

回退质量

QRandomGenerator::system() 使用操作系统设施来获取随机数,它试图从周围环境中收集真实熵来生成真正的随机数。不过,熵池有可能会耗尽,在这种情况下,操作系统会暂时退回到伪随机引擎。在任何情况下,QRandomGenerator::system() 都不会阻塞,等待收集更多的熵。

以下操作系统保证,即使熵池耗尽,其随机生成应用程序接口产生的结果至少在密码学上是安全的:苹果操作系统(达尔文)、BSD、Linux、Windows。因此,除非系统安装出现问题(如/dev/urandom 无法被当前进程读取),QRandomGenerator::system() 也能提供同样的保证。

在其他操作系统上,QRandomGenerator 会使用数值分布良好的 PRNG,但不能保证在所有情况下都能正确播种。更多信息,请查阅操作系统文档。

如果应用程序要求 QRandomGenerator 不回退到非加密质量的生成器,建议查看其操作系统文档,或将其部署限制为上述操作系统之一。

重入和线程安全

QRandomGenerator 是可重入的,这意味着多个线程可以同时对该类进行操作,只要它们对不同的对象进行操作即可。如果多个线程需要共享一个 PRNG 序列,则需要使用互斥进行外部锁定。

QRandomGenerator::global() 和QRandomGenerator::system() 返回的对象是例外:这些对象是线程安全的,任何线程都可以使用,无需外部锁定。请注意,线程安全并不扩展到复制这些对象:应始终通过引用使用这些对象。

标准 C++ 库兼容性

QRandomGenerator 是根据 C++ 标准库中对随机数引擎的要求而设计的,几乎可以在标准库引擎可以使用的所有情况下使用。这些要求的例外情况如下:

  • 除了 std::seed_seq 本身,QRandomGenerator 不支持从其他类似种子序列的类中播种;
  • QRandomGenerator 无法与std::ostream 或从std::istream 进行比较(但可复制)或流式处理。

QRandomGenerator 还与均匀分布类std::uniform_int_distributionstd:uniform_real_distribution 以及自由函数std::generate_canonical 兼容。例如,以下代码可用于生成范围为 [1, 2.5) 的浮点数:

    std::uniform_real_distribution dist(1, 2.5);
    return dist(*QRandomGenerator::global());

另请参见 QRandomGenerator64

成员类型文档

QRandomGenerator::result_type

operator() 返回类型的类型定义。即 quint32。

另请参阅 operator() 。

成员函数文档

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()。

[noexcept] QRandomGenerator::QRandomGenerator(std::seed_seq &sseq)

这是一个重载函数。

以种子序列sseq 作为种子,初始化此 QRandomGenerator 对象。使用相同种子值构建或重新填充的两个对象将产生相同的数字序列。

另请参阅 seed() 和securelySeeded()。

QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)

这是一个重载函数。

使用在beginend 范围内找到的值作为种子,初始化此 QRandomGenerator 对象。使用相同种子值构建或重新填充的两个对象将产生相同的数字序列。

此构造函数等同于

    std::seed_seq sseq(begin, end);
    QRandomGenerator generator(sseq);

另请参阅 seed() 和securelySeeded()。

QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qsizetype len)

这是一个重载函数。

使用len 数组seedBuffer 中的值作为种子初始化此 QRandomGenerator 对象。使用相同种子值构建或重新填充的两个对象将产生相同的数字序列。

此构造函数等同于

    std::seed_seq sseq(seedBuffer, seedBuffer + len);
    QRandomGenerator generator(sseq);

另请参阅 seed() 和securelySeeded()。

QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)

创建other 对象中生成器状态的副本。如果otherQRandomGenerator::system() 或其副本,该对象也将从操作系统随机生成设施中读取。在这种情况下,两个对象生成的序列将有所不同。

在所有其他情况下,新的 QRandomGenerator 对象将从other 对象在确定性序列中的相同位置开始。从这个位置开始,两个对象将生成相同的序列。

因此,不建议创建QRandomGenerator::global() 的副本。如果需要一个排他性的确定性生成器,可以考虑使用securelySeeded() 获得一个与QRandomGenerator::global() 没有任何关系的新对象。

double QRandomGenerator::bounded(double highest)

在 0(包含)和highest (不包含)之间随机生成一个 double。该函数等价于并实现为

    return generateDouble() * highest;

如果highest 参数为负数,结果也将为负数;如果参数为无限或 NaN,结果也将为无限或 NaN(即非随机)。

另请参阅 generateDouble() 和 bounded()。

int QRandomGenerator::bounded(int highest)

这是一个重载函数。

highest highest 必须为正数。

请注意,此函数不能用于获取 int 的全部 32 位范围内的值。请使用generate() 并将其转换为 int。

另请参阅 generate()、generate64() 和generateDouble()。

qint64 QRandomGenerator::bounded(qint64 highest)

这是一个重载函数。

highest highest 必须是正数。

请注意,此函数不能用于获取qint64 全部 64 位范围内的值。请使用generate64() 并将其转换为 qint64,或使用此函数的无符号版本。

注意: 此函数以循环方式实现,取决于获得的随机值。从长远来看,平均循环次数应略低于 2 次,但如果随机发生器有缺陷,此函数的执行时间可能会大大延长。

另请参见 generate()、generate64() 和generateDouble()。

quint32 QRandomGenerator::bounded(quint32 highest)

这是一个重载函数。

在 0(包含)和highest (不包含)之间的范围内生成一个 32 位随机数。使用 std::uniform_int_distribution参数 0 和highest - 1 也可以得到相同的结果。该类还可用于获取大于 32 位的数值;对于 64 位数值,也可使用 64 位 bounded() 重载函数。

例如,要获取介于 0 和 255(包括 255)之间的数值,可以写入...:

    quint32 v = QRandomGenerator::global()->bounded(256);

当然,也可以通过将generate() 的结果屏蔽到低 8 位来获得相同的值。无论哪种方法都同样有效。

请注意,该函数不能用于获取 quint32 全部 32 位范围内的值。请使用generate() 代替。

另请参阅 generate()、generate64() 和generateDouble()。

quint64 QRandomGenerator::bounded(quint64 highest)

这是一个重载函数。

在 0(包含)和highest (不包含)之间的范围内生成一个 64 位随机数。使用 std::uniform_int_distribution<quint64>参数 0 和highest - 1 也可以得到相同的结果。

请注意,此函数不能用于获取quint64 全部 64 位范围内的值。请使用generate64() 代替。

注意: 此函数是以循环方式实现的,取决于获得的随机值。从长远来看,平均循环次数应略低于 2 次,但如果随机发生器有缺陷,该函数的执行时间可能会大大延长。

另请参见 generate()、generate64() 和generateDouble()。

int QRandomGenerator::bounded(int lowest, int highest)

这是一个重载函数。

lowest (包含)和highest (不包含)之间的范围内随机生成一个 32 位数,这两个值都可以是负数,但highest 必须大于lowest

请注意,该函数不能用于获取 int 全部 32 位范围内的值。请使用generate() 并将其转换为 int。

另请参阅 generate()、generate64() 和generateDouble()。

qint64 QRandomGenerator::bounded(qint64 lowest, qint64 highest)

这是一个重载函数。

lowest (包含)和highest (不包含)之间的范围内随机生成一个 64 位数,这两个数都可以是负数,但highest 必须大于lowest

请注意,该函数不能用于获取qint64 全部 64 位范围内的数值。请使用generate64() 并将其转换为 qint64。

注意: 此函数以循环方式实现,取决于获得的随机值。从长远来看,平均循环次数应略低于 2 次,但如果随机发生器有缺陷,该函数的执行时间可能会大大延长。

另请参见 generate()、generate64() 和generateDouble()。

quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest)

这是一个重载函数。

lowest (包含)和highest (不包含)之间的范围内生成一个 32 位随机数。highest 参数必须大于lowest

使用 std::uniform_int_distribution参数lowest\a highest - 1 也可以得到相同的结果。该类还可用于获取大于 32 位的量。

例如,要获取介于 1000(含)和 2000(不含)之间的数值,可以写道

    quint32 v = QRandomGenerator::global()->bounded(1000, 2000);

请注意,该函数不能用于获取 quint32 全部 32 位范围内的值。请使用generate() 代替。

另请参阅 generate()、generate64() 和generateDouble()。

quint64 QRandomGenerator::bounded(quint64 lowest, quint64 highest)

这是一个重载函数。

lowest (包含)和highest (不包含)之间的范围内生成一个 64 位随机数。highest 参数必须大于lowest

使用 std::uniform_int_distribution<quint64>参数lowest\a highest - 1 也可得到相同结果。

请注意,此函数不能用于获取quint64 全部 64 位范围内的值。请使用generate64() 代替。

注意: 该函数是以循环方式实现的,取决于所获得的随机值。从长远来看,平均循环次数应略低于 2 次,但如果随机发生器有缺陷,该函数的执行时间可能会大大延长。

另请参见 generate()、generate64() 和generateDouble()。

void QRandomGenerator::discard(unsigned long long z)

丢弃序列中下一个z 条目。该方法等同于调用generate()z 次,并丢弃结果,如下所示:

    while (z--)
        generator.generate();

template <typename UInt, size_t N, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt (&)[N] buffer)

生成N 32 位或 64 位数量(取决于UInt 类型),并将其存储在buffer 数组中。这是一次获得多个数量的最有效方法,因为它减少了调用随机数生成器源的次数。

例如,要填充生成两个 32 位的数量,可以写入"......":

    quint32 array[2];
    QRandomGenerator::global()->fillRange(array);

也可以调用generate64() 一次,然后将 64 位数值的两半拆分。

另请参见 generate()。

template <typename UInt, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt *buffer, qsizetype count)

生成count 32 位或 64 位数量(取决于UInt 类型),并将其存储在buffer 指向的缓冲区中。这是一次获得多个数量的最有效方法,因为它减少了调用随机数发生器源的次数。

例如,要在一个包含 16 个条目的列表中填入随机数值,可以写入

    QList<quint32> list;
    list.resize(16);
    QRandomGenerator::global()->fillRange(list.data(), list.size());

另请参见 generate().

quint64 QRandomGenerator::generate64()

生成并返回一个 64 位随机数。

另请参阅 operator()() 和generate()。

quint32 QRandomGenerator::generate()

生成并返回 32 位随机数。

另请参阅 operator()() 和generate64()。

template <typename ForwardIterator> void QRandomGenerator::generate(ForwardIterator begin, ForwardIterator end)

生成 32 位数量并将其存储在beginend 之间的范围内。该函数等同于(并以):

    std::generate(begin, end, [this]() { return generate(); });

该函数符合 std::seed_seq::generate的要求,该函数需要无符号 32 位整数值。

请注意,如果 [begin, end) 范围指的是每个元素可存储超过 32 位的区域,则元素仍将仅以 32 位数据初始化。任何其他位都将为零。若要用 64 位数量填充范围,可以写入以下内容:

    std::generate(begin, end, []() { return QRandomGenerator::global()->generate64(); });

如果范围指的是连续内存(如数组或QList 中的数据),也可以使用fillRange() 函数。

另请参见 fillRange()。

double QRandomGenerator::generateDouble()

在标准范围 [0, 1](即包含 0,不包含 1)内生成一个随机 qreal。

此函数等价于

    QRandomGenerator64 rd;
    return std::generate_canonical<qreal, std::numeric_limits<qreal>::digits>(rd);

也可以使用 std::uniform_real_distribution参数 0 和 1 也可以得到相同的结果。

另请参见 generate()、generate64() 和bounded()。

[static] QRandomGenerator *QRandomGenerator::global()

返回指向共享QRandomGenerator 的指针,该共享 已通过securelySeeded() 进行了播种。该函数可用于创建随机数据,而无需为特定用途创建昂贵的安全种子QRandomGenerator 或存储相当大的QRandomGenerator 对象。

例如,下面创建了一个随机 RGB 颜色:

    return QColor::fromRgb(QRandomGenerator::global()->generate());

对该对象的访问是线程安全的,因此可以在任何没有锁的线程中使用。该对象也可以复制,复制产生的序列将与共享对象产生的序列相同。但需要注意的是,如果有其他线程访问全局对象,这些线程可能会以不可预测的时间间隔获取样本。

注意:此函数是线程安全的

另请参阅 securelySeeded() 和system()。

[static constexpr] QRandomGenerator::result_type QRandomGenerator::max()

返回QRandomGenerator 可能生成的最大值。即std::numeric_limits<result_type>::max()

另请参阅 min() 和 QRandomGenerator64::max()。

[static constexpr] QRandomGenerator::result_type QRandomGenerator::min()

返回QRandomGenerator 可能生成的最小值。即 0。

另请参阅 max() 和 QRandomGenerator64::min()。

[static] QRandomGenerator QRandomGenerator::securelySeeded()

返回通过QRandomGenerator::system() 安全播种的新QRandomGenerator 对象。该函数将为QRandomGenerator 所使用的算法获取理想的种子大小,因此是创建将保存一段时间的新QRandomGenerator 对象的推荐方法。

考虑到为确定性引擎安全播种所需的数据量,该函数有些昂贵,不应用于QRandomGenerator 的短期使用(使用该函数生成少于 2600 字节的随机数据实际上是在浪费资源)。如果不需要这么多数据,可以考虑使用QRandomGenerator::global() 而不是存储QRandomGenerator 对象。

另请参阅 global() 和system()。

void QRandomGenerator::seed(quint32 seed = 1)

使用seed 作为种子值对该对象进行重选。

[noexcept] void QRandomGenerator::seed(std::seed_seq &seed)

这是一个重载函数。

使用种子序列seed 作为种子对该对象进行重选。

[static] QRandomGenerator *QRandomGenerator::system()

返回指向共享QRandomGenerator 的指针,该指针始终使用操作系统提供的设施生成随机数。至少在以下操作系统中,系统设施被认为是加密安全的:苹果操作系统(达尔文)、BSD、Linux、Windows。其他操作系统可能也是如此。

它们也可能由真正的硬件随机数生成器支持。因此,此函数返回的QRandomGenerator 不应用于批量数据生成。相反,应使用它为QRandomGenerator 或来自 <random> 标头的随机引擎提供种子。

此函数返回的对象是线程安全的,可以在任何没有锁的线程中使用。它也可以被复制,生成的QRandomGenerator 也将访问操作系统设施,但不会生成相同的序列。

注意:该函数是线程安全的

另请参阅 securelySeeded() 和global()。

QRandomGenerator::result_type QRandomGenerator::operator()()

生成并返回 32 位随机数。

另请参阅 generate() 和generate64()。

相关非会员

bool operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2)

如果两个引擎rng1rng2 处于不同状态,或者其中一个正在从操作系统设施读取数据,而另一个没有,则返回true ,否则返回false

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.