Класс QRandomGenerator
Класс QRandomGenerator позволяет получать случайные значения с помощью генератора случайных чисел высокого качества. Подробнее...
| Заголовок: | #include <QRandomGenerator> |
| qmake: | QT += core |
| С тех пор: | Qt 5.10 |
| Наследуется от: |
Примечание: Все функции в этом классе являются взаимоисключающими.
Примечание: Эти функции также безопасны для потоков:
Открытые типы
| класс | Storage |
| typedef | result_type |
Открытые функции
| 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) |
| int | bounded(int highest) |
| quint32 | bounded(quint32 lowest, quint32 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 & | operator=(const QRandomGenerator &other) |
Статические открытые члены
| 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 позволяет получать случайные значения с помощью генератора случайных чисел высокого качества.
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() не следует использовать для генерации случайных чисел высокой частоты, чтобы пул энтропии не стал пустым. Как правило, этот класс не должен вызываться для генерации более килобайта случайных данных в секунду (примечание: это может варьироваться от системы к системе).
Если приложению нужны данные истинного ГСЧ в больших объёмах, оно должно использовать средства операционной системы (например, /dev/random в Linux) напрямую и ждать, пока энтропия станет доступной. Если приложение требует ПГСЧ криптографического качества, но не истинного случайного характера, QRandomGenerator::system() всё ещё можно использовать (см. раздел ниже).
Если не требуется ни истинный ГСЧ, ни криптографически безопасный ПГСЧ, приложения должны вместо этого использовать ПГСЧ, такие как детерминированный режим QRandomGenerator, и те, что из стандартной библиотеки C++. QRandomGenerator::system() можно использовать для инициализации этих ПГСЧ.
Качество обратного хода
QRandomGenerator::system() использует средства операционной системы для получения случайных чисел, которые пытаются собрать реальную энтропию из окружающей среды для создания истинных случайных чисел. Однако возможно, что пул энтропии исчерпается, в этом случае операционная система временно переключится на псевдослучайный генератор. QRandomGenerator::system() ни в коем случае не будет блокироваться, ожидая сбора дополнительной энтропии.
Следующие операционные системы гарантируют, что результаты их API для генерации случайных чисел будут как минимум криптографически безопасного качества, даже если пул энтропии исчерпан: Apple OS (Darwin), BSD, 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 и qrand().
Документация типов-членов
typedef QRandomGenerator::result_type
Тип, возвращаемый оператором operator(). То есть, quint32.
См. также operator().
Документация функций-членов
QRandomGenerator::QRandomGenerator(quint32 seedValue = 1)
Инициализирует этот объект QRandomGenerator значением seedValue в качестве начального. Два объекта, созданные или повторно инициализированные с одинаковым значением начального значения, будут генерировать одинаковую последовательность чисел.
См. также seed() и securelySeeded().
QRandomGenerator::QRandomGenerator(const quint32 (&)[N] seedBuffer = ...)
Это перегруженная функция.
Инициализирует этот объект QRandomGenerator значениями из массива seedBuffer в качестве начального. Два объекта, созданные или повторно инициализированные с одинаковым значением начального значения, будут генерировать одинаковую последовательность чисел.
См. также 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(std::seed_seq &sseq)
Это перегруженная функция.
Инициализирует этот объект QRandomGenerator последовательностью инициализации sseq в качестве начального. Два объекта, созданные или повторно инициализированные с одинаковым значением начального значения, будут генерировать одинаковую последовательность чисел.
См. также seed() и securelySeeded().
QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end)
Это перегруженная функция.
Инициализирует этот объект QRandomGenerator значениями из диапазона от begin до end в качестве начального. Два объекта, созданные или повторно инициализированные с одинаковым значением начального значения, будут генерировать одинаковую последовательность чисел.
Этот конструктор эквивалентен:
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 (исключительно). Эта функция эквивалентна и реализована как:
return generateDouble() * highest;
См. также 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().
int QRandomGenerator::bounded(int highest)
Это перегруженный метод.
Генерирует одно случайное 32-битное значение в диапазоне от 0 (включительно) до highest (исключительно). highest не должно быть отрицательным.
Обратите внимание, что этот метод не может быть использован для получения значений в полном 32-битном диапазоне int. Вместо этого используйте generate() и приведение к типу int.
См. также generate(), generate64() и generateDouble().
quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest)
Это перегруженный метод.
Генерирует одно случайное 32-битное значение в диапазоне от lowest (включительно) до highest (исключительно). Тот же результат можно получить, используя 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 lowest, int highest)
Это перегруженный метод.
Генерирует одно случайное 32-битное значение в диапазоне от lowest (включительно) до highest (исключительно), оба значения могут быть отрицательными.
Обратите внимание, что этот метод не может быть использован для получения значений в полном 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) (то есть, включая ноль и исключая 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 OSes (Darwin), BSD, Linux, Windows. Это также может быть верно и для других операционных систем.
Они также могут быть подкреплены истинным генератором случайных чисел аппаратного обеспечения. По этой причине QRandomGenerator, возвращаемый этой функцией, не должен использоваться для генерации данных большими объемами. Вместо этого используйте его для инициализации QRandomGenerator или генератора случайных чисел из заголовка <random>.
Объект, возвращаемый этой функцией, потокобезопасен и может использоваться в любом потоке без блокировок. Он также может быть скопирован, и полученный QRandomGenerator также будет обращаться к средствам операционной системы, но они не будут генерировать ту же последовательность.
Примечание: Эта функция потокобезопасна.
См. также securelySeeded() и global().
QRandomGenerator::result_type QRandomGenerator::operator()()
Генерирует 32-битное случайное значение и возвращает его.
См. также generate() и generate64().
QRandomGenerator &QRandomGenerator::operator=(const QRandomGenerator &other)
Оператор присваивания по значению.
Связанные нечленные функции
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.12/qrandomgenerator.html