排出std :: random_device的熵

时间:2018-12-27 12:03:49

标签: c++ random g++ entropy

我正在使用std::random_device,并希望检查其剩余的熵。根据cppreference.com:

  

std::random_device::entropy

double entropy() const noexcept;
     

[...]

     

返回值

     

设备熵的值;如果不适用,则为零。

     

注释

     

此功能在某些标准库中未完全实现。例如,即使设备不确定,LLVM libc ++始终返回零。相比之下,Microsoft Visual C ++实现始终返回32,而boost.random返回10。

     

可以使用ioctl RNDGETENTCNT获得Linux内核设备/ dev / urandom的熵-这是GNU libstdc ++自8.1版本起使用的std :: random_device :: entropy()

因此在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
}

Live demo on Coliru (which runs under Linux, right?)

我期望从设备生成数字会消耗其熵。但事实并非如此。

发生了什么事?

2 个答案:

答案 0 :(得分:2)

该库返回的熵值不会大于其结果类型中的位数(在这种情况下为32)。

请参见libstd code

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

您链接到的文档对此进行了解释:

  

获得随机数设备熵的估计值,该熵是介于0和log 2(max()+ 1)之间的浮点值(等于std :: numeric_limits :: digits)。

答案 1 :(得分:0)

您可以了解here如何实现.entropy()

基本上,entropy()调用ioctl(fd, RNDGETENTCNT, &ent)并返回ent(在根据需要将其限制为目标类型的最大位数之后)。

碰巧的是,它在您进行drain_entropy通话后没有改变。

您可以手动实现此方法,并观察其行为是否相同。 即使消除了夹紧,熵也几乎没有受到影响(甚至可能增加)。