Истощение энтропии std :: random_device

я использую 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, верно?)

Я ожидаю, что генерация чисел из устройства истощает его энтропию. Но это не так.

Что происходит?

0

Решение

Библиотека не будет возвращать значение энтропии, превышающее число битов в ее типе результата, который в данном случае равен 32.

Увидеть код libstd:

const int max = sizeof(result_type) * __CHAR_BIT__;
if (ent > max)
ent = max;

Документация, на которую вы ссылались, объясняет это:

Получает оценку энтропии устройства со случайным числом, которая представляет собой значение с плавающей запятой от 0 до log 2 (max () + 1) (что равно std :: numeric_limits :: digits).

2

Другие решения

Вы можете увидеть, как .entropy() реализуется Вот.

В основном, entropy() звонки ioctl(fd, RNDGETENTCNT, &ent) и возвращается ent (после зажима это максимальное количество битов в целевом типе, как требуется).

Так получилось, что после твоего drain_entropy вызов.

Вы можете вручную реализовать этот метод и увидеть, что он ведет себя так же.
Даже если вы удалите зажим, энтропия практически не пострадает (она может даже увеличиться).

0

По вопросам рекламы [email protected]