C ++ - 从/ dev / urandom中提取随机数

时间:2016-03-01 15:04:20

标签: c++ random

我需要许多加密安全号码,因此我考虑从/dev/urandom中提取随机性,然后转换"它(比如)unsigned long long int。我想它应该是非常有效的,似乎它在加密方面是安全的,但我将在未来更多地研究这方面 现在的问题是:我该怎么做?

我找到了这段代码:

char * block;
short size = 1;
ifstream urandom("/dev/urandom", ios::in|ios::binary);
urandom.read(block,size);
urandom.close();

有意义吗?我如何将我得到的内容转换为我想要的类型?

编辑 - 使用C ++ 11的random接口

根据评论中的建议,我尝试对整数使用统一分布,并将random_device初始化为/dev/urandom。这是代码:

std::uniform_int_distribution<unsigned int> dist(0, modulus-1);
std::random_device urandom("/dev/urandom");
for(unsigned int i = start ; i < end ; ++i)
{
    vector[i] = dist(urandom);
}

问题是这段代码比以前慢了大约1000倍(我使用的是xorshift128 +生成器):5毫秒,差不多5秒。这是正常的吗?老实说,我认为从/dev/urandom流入字节并将它们转换为unsigned int会更快......我错过了什么?

1 个答案:

答案 0 :(得分:4)

因此,您的第一个示例不正确,会导致未定义的行为。

char*块没有指向任何已分配的数据,因此ifstream::read实际上会写入未分配的内存。

除此之外,size的类型为signed short,而应为size_t

为了阅读unsigned long long int,你可以使用`ifstream&#39;像这样:

#include <iostream>
#include <fstream>

int main()
{
    using namespace std;
    unsigned long long int random_value = 0; //Declare value to store data into
    size_t size = sizeof(random_value); //Declare size of data
    ifstream urandom("/dev/urandom", ios::in|ios::binary); //Open stream
    if(urandom) //Check if stream is open
    {
        urandom.read(reinterpret_cast<char*>(&random_value), size); //Read from urandom
        if(urandom) //Check if stream is ok, read succeeded
        {
            std::cout << "Read random value: " << random_value << std::endl;
        }
        else //Read failed
        {
            std::cerr << "Failed to read from /dev/urandom" << std::endl;
        }
        urandom.close(); //close stream
    }
    else //Open failed
    {
        std::cerr << "Failed to open /dev/urandom" << std::endl;
    }
    return 0;
}

有趣的部分是它实际上用urandom.read(reinterpret_cast<char*>(&random_value), size);

读取的位置

size应该清楚。通过使用sizeof,我们得到了我们想要将随机值存储到的数据的实际大小(以字节为单位)。这很有用,因为这个值在不同的体系结构上可能会有所不同(例如32位和64位)。
如果您在此处传递的数据类型是指针,请注意。 sizeof只返回指针的大小,而不是指向它的数据的大小。

random_value的类型为unsigned long long int。所以&random_value是适当指针unsigned long long int*的类型。 但是我们想要读取字节(char),因此需要将值从unsigned long long int*更改/转换为char*reinterpret_cast<char*>(&random_value))。