Класс QRandomGenerator
Класс QRandomGenerator позволяет получить случайные значения с помощью генератора псевдослучайных чисел высокого качества. Подробнее...
| Заголовок: | #include <QRandomGenerator> |
| qmake: | QT += core |
| С момента: | Qt 5.10 |
| Наследуется от: |
Этот класс был представлен в Qt 5.10.
Примечание: Все функции в этом классе являются перевходными.
Примечание: Эти функции также являются потокобезопасными:
Открытые типы
| typedef | result_type |
Открытые функции
| QRandomGenerator(const QRandomGenerator &other) | |
| QRandomGenerator(const quint32 *begin, const quint32 *end) | |
| QRandomGenerator(std::seed_seq &sseq) | |
| QRandomGenerator(const quint32 *seedBuffer, qsizetype len) | |
| QRandomGenerator(const quint32 (&)[N] seedBuffer = ...) | |
| QRandomGenerator(quint32 seedValue = 1) | |
| double | bounded(double highest) |
| quint32 | bounded(quint32 highest) |
| quint32 | bounded(quint32 lowest, quint32 highest) |
| int | bounded(int highest) |
| int | bounded(int lowest, int highest) |
| void | discard(unsigned long long z) |
| void | fillRange(UInt *buffer, qsizetype count) |
| void | fillRange(UInt (&)[N] buffer = ...) |
| 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) |
| bool | operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2) |
Подробное описание
QRandomGenerator можно использовать для генерации случайных значений с помощью генератора псевдослучайных чисел высокого качества. Как и C++ генераторы случайных чисел, QRandomGenerator можно инициализировать с помощью пользовательских значений через конструктор. При инициализации последовательность чисел, генерируемых этим классом, является детерминированной. То есть, с одинаковыми данными инициализации QRandomGenerator будет генерировать одну и ту же последовательность чисел. Но с различными значениями инициализации результаты должны быть значительно отличными.
QRandomGenerator::securelySeeded() можно использовать для создания QRandomGenerator, который надежно инициализируется с помощью QRandomGenerator::system(), что означает, что последовательность генерируемых чисел нельзя легко предсказать. Кроме того, 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) (то есть, включая ноль и не включая 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. Эта функция будет использовать аппаратные средства для генерации случайных чисел, где это возможно. В таких системах эти средства являются истинными генераторами случайных чисел. Однако, если они являются истинными генераторами, эти средства имеют ограниченные источники энтропии, и, таким образом, могут не генерировать результаты, если их пул энтропии исчерпан.
Если это произойдёт, сначала операционная система, а затем QRandomGenerator перейдут к псевдогенераторам случайных чисел с ухудшающимися характеристиками (генератор Qt по умолчанию является самым простым). Гарантируется ли, что эти генераторы по-прежнему обладают криптографической надёжностью, зависит от реализации. Поэтому, QRandomGenerator::system() не следует использовать для генерации случайных чисел с высокой частотой, чтобы не исчерпать пул энтропии. В качестве правила, этот класс не следует использовать для генерации более килобайта случайных данных в секунду (прим.: это может зависеть от системы).
Если приложению требуется большое количество данных от истинного генератора случайных чисел (True RNG), оно должно использовать средства операционной системы (такие как /dev/random в Linux) напрямую и ждать, пока энтропия станет доступной. Если приложение требует PRNG-движки криптографической надёжности, но не истинного случайного характера, QRandomGenerator::system() всё ещё может быть использовано (см. раздел ниже).
Если не требуется ни True RNG, ни криптографически защищённый PRNG, приложения должны вместо этого использовать PRNG-движки, такие как детерминированный режим QRandomGenerator, и аналогичные из стандартной библиотеки C++. QRandomGenerator::system() может использоваться для инициализации этих движков.
Качество по умолчанию
QRandomGenerator::system() использует средства операционной системы для получения случайных чисел, которые пытаются собрать реальную энтропию из окружающей среды для генерации истинно случайных чисел. Однако возможно, что пул энтропии исчерпан, в этом случае операционная система временно перейдёт к псевдослучайному генератору. В никаких обстоятельствах QRandomGenerator::system() не будет ожидать сбора больше энтропии.
Следующие операционные системы гарантируют, что результаты их API для генерации случайных чисел будут, по крайней мере, криптографически надёжны, даже если пул энтропии исчерпан: Apple OSes (Darwin), BSD, Linux, Windows. Если отсутствуют проблемы с установкой системы (например, /dev/urandom недоступен для текущего процесса), QRandomGenerator::system() будет иметь такие же гарантии.
В других операционных системах QRandomGenerator переключится на PRNG с хорошим распределением чисел, но не может гарантировать правильную инициализацию во всех случаях. Для получения дополнительной информации, пожалуйста, обратитесь к документации ОС.
Приложениям, которым необходимо, чтобы QRandomGenerator не переходил к генераторам с низким криптографическим качеством, рекомендуется проверить документацию своей операционной системы или ограничить развертывание одной из вышеуказанных операционных систем.
Реентерабельность и безопасность потоков
QRandomGenerator реентерабелен, что означает, что несколько потоков могут работать с этим классом одновременно, при условии, что они работают с разными объектами. Если нескольким потокам нужно использовать одну последовательность PRNG, требуется внешняя блокировка с помощью мьютекса.
Исключениями являются объекты, возвращаемые 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 и qrand().
Документация по типам членов
typedef QRandomGenerator::result_type
Псевдоним типа, возвращаемого operator(). То есть, quint32.
См. также operator().
Документация по членам-функциям
QRandomGenerator::QRandomGenerator(const QRandomGenerator &other)
Создаёт копию состояния генератора в объекте other. Если other является QRandomGenerator::system() или копией этого объекта, этот объект также будет считывать данные из средств операционной системы для генерации случайных чисел. В этом случае последовательности, генерируемые двумя объектами, будут разными.
Во всех остальных случаях новый объект QRandomGenerator начнёт с той же позиции в детерминированной последовательности, что и объект other. Оба объекта будут генерировать одну и ту же последовательность с этого момента.
По этой причине не рекомендуется создавать копию QRandomGenerator::global(). Если нужно получить эксклюзивный детерминированный генератор, следует использовать securelySeeded() для получения нового объекта, не связанного с QRandomGenerator::global().
QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
Это перегруженная функция.
Инициализирует этот объект QRandomGenerator значениями, найденными в диапазоне от begin до end, как семенами. Два объекта, созданные или повторно инициализированные с тем же значением семени, будут генерировать одну и ту же последовательность чисел.
Этот конструктор эквивалентен:
std::seed_seq sseq(begin, end);
QRandomGenerator generator(sseq); См. также seed() и securelySeeded().
QRandomGenerator::QRandomGenerator(std::seed_seq &sseq)
Это перегруженная функция.
Инициализирует этот объект QRandomGenerator последовательностью семян sseq в качестве семени. Два объекта, созданные или повторно инициализированные с тем же значением семени, будут генерировать одну и ту же последовательность чисел.
См. также seed() и securelySeeded().
QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qsizetype len)
Это перегруженная функция.
Инициализирует этот объект QRandomGenerator значениями, найденными в массиве seedBuffer, как семенами, используя len элементов. Два объекта, созданные или повторно инициализированные с тем же значением семени, будут генерировать одну и ту же последовательность чисел.
Этот конструктор эквивалентен:
std::seed_seq sseq(seedBuffer, seedBuffer + len);
QRandomGenerator generator(sseq); См. также seed() и securelySeeded().
QRandomGenerator::QRandomGenerator(const quint32 (&)[N] seedBuffer = ...)
Это перегруженная функция.
Инициализирует этот объект QRandomGenerator значениями, найденными в массиве seedBuffer, как семенами. Два объекта, созданные или повторно инициализированные с тем же значением семени, будут генерировать одну и ту же последовательность чисел.
См. также seed() и securelySeeded().
QRandomGenerator::QRandomGenerator(quint32 seedValue = 1)
Инициализирует этот объект QRandomGenerator значением seedValue в качестве семени. Два объекта, созданные или повторно инициализированные с тем же значением семени, будут генерировать одну и ту же последовательность чисел.
См. также seed() и securelySeeded().
double QRandomGenerator::bounded(double highest)
Генерирует одно случайное вещественное число в диапазоне от 0 (включительно) до highest (исключительно). Эта функция эквивалентна и реализована как:
return generateDouble() * highest;
Если параметр highest отрицательный, результат также будет отрицательным; если он бесконечен или NaN, результат также будет бесконечным или NaN (то есть не случайным).
См. также generateDouble() и bounded().
quint32 QRandomGenerator::bounded(quint32 highest)
Это перегруженная функция.
Генерирует одно случайное 32-битовое целое число в диапазоне от 0 (включительно) до highest (исключительно). Тот же результат можно получить, используя std::uniform_int_distribution с параметрами 0 и highest - 1. Этот класс также может быть использован для получения величин больше 32 бит.
Например, чтобы получить значение от 0 до 255 (включительно), необходимо написать:
quint32 v = QRandomGenerator::bounded(256);
Естественно, то же самое можно получить, маскируя результат generate() только до младших 8 битов. Любое решение так же эффективно.
Обратите внимание, что эта функция не может быть использована для получения значений в полном 32-битном диапазоне quint32. Используйте вместо этого generate().
См. также generate(), generate64(), и generateDouble().
quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest)
Это перегруженная функция.
Генерирует одно случайное 32-битовое целое число в диапазоне от lowest (включительно) до highest (исключительно). Параметр highest должен быть больше lowest.
Тот же результат можно получить, используя std::uniform_int_distribution с параметрами lowest и \a highest - 1. Этот класс также можно использовать для получения значений, больших, чем 32 бита.
Например, для получения значения между 1000 (включительно) и 2000 (исключительно), необходимо написать:
quint32 v = QRandomGenerator::bounded(1000, 2000);
Обратите внимание, что эта функция не может использоваться для получения значений в полном 32-битном диапазоне quint32. Используйте вместо этого generate().
См. также generate(), generate64() и generateDouble().
int QRandomGenerator::bounded(int highest)
Это перегруженная функция.
Генерирует одно случайное 32-битное значение в диапазоне от 0 (включительно) до highest (исключительно). highest должно быть положительным.
Обратите внимание, что эта функция не может использоваться для получения значений в полном 32-битном диапазоне int. Вместо этого используйте generate() и приведите результат к типу int.
См. также generate(), generate64() и generateDouble().
int QRandomGenerator::bounded(int lowest, int highest)
Это перегруженная функция.
Генерирует одно случайное 32-битное значение в диапазоне от lowest (включительно) до highest (исключительно), оба из которых могут быть отрицательными, но highest должно быть больше lowest.
Обратите внимание, что эта функция не может использоваться для получения значений в полном 32-битном диапазоне int. Вместо этого используйте generate() и приведите результат к типу int.
См. также generate(), generate64() и generateDouble().
void QRandomGenerator::discard(unsigned long long z)
Отбрасывает следующие z элементов из последовательности. Этот метод эквивалентен вызову generate() z раз и отбрасыванию результата, как в примере:
while (z--)
generator.generate(); void QRandomGenerator::fillRange(UInt *buffer, qsizetype count)
Генерирует count 32- или 64-битных значений (в зависимости от типа UInt) и сохраняет их в буфере, указанном buffer. Это наиболее эффективный способ получения более одного значения за раз, так как это уменьшает количество вызовов источнику генератора случайных чисел.
Например, чтобы заполнить вектор из 16 элементов случайными значениями, можно написать:
QVector<quint32> vector;
vector.resize(16);
QRandomGenerator::fillRange(vector.data(), vector.size()); См. также generate().
void QRandomGenerator::fillRange(UInt (&)[N] buffer = ...)
Генерирует N 32- или 64-битных значений (в зависимости от типа UInt) и сохраняет их в массиве buffer. Это наиболее эффективный способ получения более одного значения за раз, так как это уменьшает количество вызовов источнику генератора случайных чисел.
Например, чтобы сгенерировать два 32-битных значения, можно написать:
quint32 array[2];
QRandomGenerator::fillRange(array); Также было бы возможно сделать один вызов generate64() и затем разделить две половины 64-битного значения.
См. также generate().
quint64 QRandomGenerator::generate64()
Генерирует 64-битное случайное значение и возвращает его.
См. также operator()() и generate().
quint32 QRandomGenerator::generate()
Генерирует 32-битное случайное значение и возвращает его.
См. также operator()() и generate64().
void QRandomGenerator::generate(ForwardIterator begin, ForwardIterator end)
Генерирует 32-битные значения и сохраняет их в диапазоне между begin и end. Эта функция эквивалентна (и реализована как):
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(); }); Если диапазон относится к непрерывной памяти (например, массив или данные из QVector), можно также использовать функцию fillRange().
См. также fillRange().
double QRandomGenerator::generateDouble()
Генерирует одно случайное значение типа 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().
[static] QRandomGenerator *QRandomGenerator::global()
Возвращает указатель на общий QRandomGenerator, который был инициализирован с помощью securelySeeded(). Эта функция должна использоваться для создания случайных данных без дорогостоящего создания QRandomGenerator с безопасным начальным значением для конкретного использования или хранения довольно большого объекта QRandomGenerator.
Например, следующее создаёт случайный цвет RGB:
return QColor::fromRgb(QRandomGenerator::global()->generate());
Доступ к этому объекту потокобезопасен, и поэтому он может использоваться в любом потоке без блокировок. Объект также может быть скопирован, и последовательность, генерируемая копией, будет такой же, как у общего объекта. Однако, если есть другие потоки, обращающиеся к глобальному объекту, эти потоки могут получать образцы в непредсказуемые моменты.
Примечание: Эта функция потокобезопасна.
См. также securelySeeded() и system().
[static] QRandomGenerator::result_type QRandomGenerator::max()
Возвращает максимальное значение, которое может сгенерировать QRandomGenerator. То есть, std::numeric_limits<result_type>::max().
См. также min() и QRandomGenerator64::max().
[static] QRandomGenerator::result_type QRandomGenerator::min()
Возвращает минимальное значение, которое может сгенерировать QRandomGenerator. То есть, 0.
См. также max() и QRandomGenerator64::min().
[static] QRandomGenerator QRandomGenerator::securelySeeded()
Возвращает новый объект QRandomGenerator, который был сгенерирован с помощью QRandomGenerator::system(). Эта функция получит идеальный размер начального значения для алгоритма, используемого QRandomGenerator, и поэтому является рекомендуемым способом создания нового объекта QRandomGenerator, который будет храниться некоторое время.
Учитывая количество данных, необходимых для безопасной инициализации детерминированного генератора, эта функция довольно ресурсоёмкая и не должна использоваться для кратковременного использования QRandomGenerator (использование её для генерации менее 2600 байт случайных данных фактически является пустой тратой ресурсов). Если использование не требует стольких данных, рассмотрите использование QRandomGenerator::global() и не храните объект QRandomGenerator вместо этого.
См. также global() и system().
void QRandomGenerator::seed(quint32 seed = 1)
Переинициализирует этот объект, используя значение seed в качестве начального.
void QRandomGenerator::seed(std::seed_seq &seed)
Это перегруженная функция.
Переинициализирует этот объект, используя последовательность начальных значений seed.
[static] QRandomGenerator *QRandomGenerator::system()
Возвращает указатель на общий QRandomGenerator, который всегда использует возможности операционной системы для генерации случайных чисел. Возможности системы считаются криптографически безопасными как минимум на следующих операционных системах: Apple OS (Darwin), 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)
Возвращает true, если два генератора rng1 и rng2 находятся в разных состояниях или если один из них считывает данные с ресурсов операционной системы, а другой — нет, в противном случае — false.
bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
Возвращает true, если два генератора rng1 и rng2 находятся в одинаковых состояниях или оба считывают данные с ресурсов операционной системы, в противном случае — false.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.14/qrandomgenerator.html