Мне нужен генератор «случайных» чисел, который выдает тот же результат для заданного начального числа в Windows, Mac, Linux, iOS и Android. Сейчас попробовал std::rand
а также boost::random_int_generator
с boost::mt19937
но, к сожалению, результат отличается для Windows и Mac.
Кто-нибудь знает о реализации (C ++), которая надежно работает на всех платформах?
РЕДАКТИРОВАТЬ 1:
Чтобы быть более конкретным, разница между числами из boost::mt19937
в Windows и Mac видно, что в Windows (2) генерируются дополнительные блоки чисел. Это выглядит действительно странно, потому что большинство чисел совпадают с этими блоками, присутствующими только в Windows.
РЕДАКТИРОВАТЬ 2:
boost::mt19937
надежно работает на всех платформах. Наши проблемы не были ошибкой там.
Вы можете попробовать PCG-Random, из http://www.pcg-random.org/
порядочный, быстрый, портативный
Если вам не нужен слишком качественный ГСЧ, вы можете реализовать его самостоятельно в виде однострочника в соответствии с описанием здесь: https://en.wikipedia.org/wiki/Linear_congruential_generator В последнее время линейные конгруэнтные гены получили довольно дурную славу, но для многих практических целей они хороши.
Пока вы осторожны с использованием только типов гарантированного размера (uint32_t и т. Д.), Все будет в порядке на всех платформах.
Если вам нужен более качественный ГСЧ, еще раз вы можете реализовать Mersenne Twister (https://en.wikipedia.org/wiki/Mersenne_Twister) сами, но это будет сложнее.
Еще один способ — использовать AES (или любой другой блочный шифр в этом отношении, например Chacha20) в режиме CTR (используя некоторый предопределенный ключ) в качестве PRNG; это будет самое известное (криптографическое) качество :-). Это не займет много кода на вашей стороне, но вам нужно будет связать реализацию AES (они широко доступны).
РЕДАКТИРОВАТЬ: пример псевдокода для иллюстрации PRNG на основе криптографии:
class CryptoBasedPRNG {
uint128_t key;
uint128_t count;
CryptoBasedPRNG(whatever-type seed) {
//derive key and initial counter from seed
// we'll be using SHA256, but any other split should do (like odd bits/even bits of seed)
uint256_t sha = sha256(seed);
key = low_128bits(sha);
count = high_128bits(sha);
}
uint128_t random_128_bits() {
count += 1;//with wraparound
return aes128(key,count);//encrypting 'count' as input data for aes128 (in ECB mode, if anybody asks about mode at this point)
}
}
Скорее просто и очень случайно.
Различные числа привели к куску glm
код, который мы использовали. Они используют неопределенный порядок оценки аргументов, что хорошо для почти случайных целей, но не для случаев, когда вам нужны детерминированные числа (очевидно). Поэтому мы исправили код для наших целей и успешно используем boost::mt19937
на Windows, Mac, Linux, Android и iOS.
Извините за путаницу.