我需要许多加密安全号码,因此我考虑从/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();
有意义吗?我如何将我得到的内容转换为我想要的类型?
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
会更快......我错过了什么?
答案 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)
)。