[英]Draining the entropy of std::random_device
我正在使用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
}
我期望從設備生成數字會消耗其熵。 但事實並非如此。
發生了什么?
該庫將不會返回大於其結果類型的位數(在這種情況下為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
調用之后沒有改變。
您可以手動實現此方法,並觀察其行為是否相同。 即使消除了夾緊,熵也幾乎沒有受到影響(甚至可能增加)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.