C++ - 从/dev/urandom 中提取随机数 [英] C++ - Extracting random numbers from /dev/urandom

查看:309
本文介绍了C++ - 从/dev/urandom 中提取随机数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要许多加密安全的数字,所以我想从 /dev/urandom 中提取随机性,然后转换"它变成(比如说)unsigned long long int.我想它应该是非常有效的,而且它似乎在密码学上是安全的,但我将来会更多地研究这方面.
现在的问题是:我该怎么做?

I need many cryptographically secure numbers, so I was thinking about extracting randomness from /dev/urandom and then "converting" it into (say) unsigned long long int. I guess it should be very efficient and it seems it is cryptographically secure, but I will investigate this aspect more in the future.
Now the question is: how can I do so?

我找到了这个代码:

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

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

Does it make sense? And how do I convert what I get to the type I desire?

根据评论中的建议,我尝试使用整数上的均匀分布和初始化为 /dev/urandomrandom_device.代码如下:

Following a suggestion from the comments, I tried using a uniform distribution over the integers and a random_device initialized as /dev/urandom. Here is the code:

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

The problem is that this code is approximately 1000 times slower than before (I was using a xorshift128+ generator): 5 milliseconds vs. almost 5 seconds. Is this normal? Honestly, I thought that streaming bytes in from /dev/urandom and converting them to unsigned int would have been way faster... Am I missing something?

推荐答案

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

So first of your example is incorrect and would cause undefined behaviour.

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

The char* block isn't pointing to any allocated data, so the ifstream::read would actually write into unallocated memory.

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

Apart from this the type of size is signed short while it should be size_t.

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

In order to read a unsigned long long int you could use `ifstream' like this:

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

The interesting part would be where this actually reads with urandom.read(reinterpret_cast<char*>(&random_value), size);

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

The size should be clear. By using sizeof we get the actual size in bytes of the data we want to store the random value into. This is useful as this value might be different on different architectures (e.g. 32-bit and 64-bit).
Be careful if the data type you pass here is a pointer. sizeof will only return the size of the pointer and not the size of the data it is pointing to.

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

random_value is of type unsigned long long int. So &random_value is the type of the appropriate pointer unsigned long long int*. But we want to read bytes (char) and therefore need to change/cast the value from unsigned long long int* to char* (reinterpret_cast<char*>(&random_value)).

这篇关于C++ - 从/dev/urandom 中提取随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆