я использую std::random_device
и хотел бы проверить оставшуюся энтропию. По данным cppreference.com:
[…]double entropy() const noexcept;
Возвращаемое значение
Значение энтропии устройства или ноль, если не применимо.
Заметки
Эта функция не полностью реализована в некоторых стандартных библиотеках. Например, LLVM libc ++ всегда возвращает ноль, даже если устройство недетерминировано. Для сравнения, реализация Microsoft Visual C ++ всегда возвращает 32, а boost.random возвращает 10.
Энтропия устройства ядра Linux / dev / urandom может быть получена с помощью ioctl RNDGETENTCNT — это то, что std :: random_device :: entropy () в GNU libstdc ++ использует начиная с версии 8.1
Так что под Linux ang g ++> = 8.1 я должен быть хорошим … но я не
#include <random>
#include <iostream>
void drain_entropy(std::random_device& rd, std::size_t count = 1)
{
while (count --> 0) {
volatile const int discard = rd();
(void) discard;
}
}
int main()
{
std::random_device rd;
std::cout << "Entropy: " << rd.entropy() << '\n'; // Entropy: 32
drain_entropy(rd, 1'000'000);
std::cout << "Entropy: " << rd.entropy() << '\n'; // Entropy: 32
}
Живая демоверсия на Coliru (которая работает под Linux, верно?)
Я ожидаю, что генерация чисел из устройства истощает его энтропию. Но это не так.
Что происходит?
Библиотека не будет возвращать значение энтропии, превышающее число битов в ее типе результата, который в данном случае равен 32.
Увидеть код libstd:
const int max = sizeof(result_type) * __CHAR_BIT__;
if (ent > max)
ent = max;
Документация, на которую вы ссылались, объясняет это:
Получает оценку энтропии устройства со случайным числом, которая представляет собой значение с плавающей запятой от 0 до log 2 (max () + 1) (что равно std :: numeric_limits :: digits).
Вы можете увидеть, как .entropy()
реализуется Вот.
В основном, entropy()
звонки ioctl(fd, RNDGETENTCNT, &ent)
и возвращается ent
(после зажима это максимальное количество битов в целевом типе, как требуется).
Так получилось, что после твоего drain_entropy
вызов.
Вы можете вручную реализовать этот метод и увидеть, что он ведет себя так же.
Даже если вы удалите зажим, энтропия практически не пострадает (она может даже увеличиться).