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

标签 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 接口(interface)

根据评论的建议,我尝试使用整数的均匀分布和初始化为 /dev/urandomrandom_device。这是代码:

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 会更快......我错过了什么吗?

最佳答案

所以你的第一个例子是不正确的,会导致未定义的行为。

char* block 没有指向任何分配的数据,所以 ifstream::read实际上会写入未分配的内存。

除此之外 size 的类型是signed short虽然它应该是 size_t .

为了阅读unsigned long long int你可以像这样使用 `ifstream':

#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))。

关于C++ - 从/dev/urandom 中提取随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35726331/

相关文章:

c++ - 将元组转换为对

c++ - 尽管 namespace 正确,但重复出现错误

java - 能否在 C/C++ 中提取 Java ZipEntry

arrays - 打乱数组,使元素移动不超过 K 个位置

random - 制作一个没有二元运算符的噪声函数?

c++ - 最大输出不正确

c++ - 必须在 std::vector<std::thread> 中加入 std::thread 两次以避免从线程 dtor 终止

c++ - 正确实现 condition_variable timed_wait

python | 26个名为a-z的列表,每个字母都是字符串,随机选择字母,如何选择列表

matlab - 在 MATLAB 中创建一个 1's and 0' s 矩阵,其中 1 的数量有限制