簡體   English   中英

排出std :: random_device的熵

[英]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
}

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調用之后沒有改變。

您可以手動實現此方法,並觀察其行為是否相同。 即使消除了夾緊,熵也幾乎沒有受到影響(甚至可能增加)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM