我正在使用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?)
我期望从设备生成数字会消耗其熵。但事实并非如此。
发生了什么事?
答案 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
通话后没有改变。
您可以手动实现此方法,并观察其行为是否相同。 即使消除了夹紧,熵也几乎没有受到影响(甚至可能增加)。