Ger*_*ner 13 c++ random distribution c++11
我的要求是生成随机字节的数据(非随机数),也就是统一分布的位.
因此,我想知道使用C++ 11/14随机设施执行此操作的正确/有效方法是什么.我的例子有环顾四周,但他们都似乎把重点放在数生成(整数,浮点数等)
我正在使用的当前解决方案如下:
#include <vector>
#include <random>
int main()
{
std::random_device rd;
std::uniform_int_distribution<int> dist(0,255);
std::vector<char> data(1000);
for (char& d : data)
{
d = static_cast<char>(dist(rd) & 0xFF);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
小智 28
你要找的是std::independent_bits_engine适配器:
#include <vector>
#include <random>
#include <climits>
#include <algorithm>
#include <functional>
using random_bytes_engine = std::independent_bits_engine<
std::default_random_engine, CHAR_BIT, unsigned char>;
int main()
{
random_bytes_engine rbe;
std::vector<unsigned char> data(1000);
std::generate(begin(data), end(data), std::ref(rbe));
}
Run Code Online (Sandbox Code Playgroud)
请注意,在一般情况下,接受的答案并不严格正确 - 随机引擎生成属于范围[ min(),max()]的无符号值,这不一定涵盖结果类型的所有可能值(例如std::minstd_rand0::min() == 1),因此您可能会得到如果直接使用引擎则不均匀分布的随机字节.但是,对于std::random_device范围是[ std::numeric_limits<result_type>::min(),std::numeric_limits<result_type>::max()],所以这个特定的引擎也可以在没有适配器的情况下正常工作.
bam*_*s53 13
分布采用随机位并将其转换为数字.如果你真的想要随机位,那么你想要使用一个引擎:
特别是,这些要求为产生位序列的类型和对象指定算法接口,其中每个可能的位值是均匀可能的.3
对URNG对象的单次调用允许生成并传递许多(通常为32或更多)位,将这些位作为无符号整数类型的单个打包值返回.4 N3847
random_device 碰巧被指定为访问均匀分布的位很容易:
std::random_device engine;
unsigned x = engine(); // sizeof(unsigned) * CHAR_BIT random bits
Run Code Online (Sandbox Code Playgroud)
请注意,其他引擎可能无法使得获得均匀随机位变得非常容易random_device,因为返回的位数少于result_type可以容纳的位数,甚至可以通过有效返回小数位来实现.
如果你担心的是unsigned大小是实现定义的,所以random_device返回一个实现定义的位数,你可以编写一个适配器,在给你之前收集足够的位,或者给你足够的位并缓存其余的位为您的下一个请求.(您也可以这样做来处理其他表现出上述问题的引擎.)
回答你的问题:你不能。
该标准不允许std::uniform_int_distribution进行模板上char,signed char或unsigned char。有人认为这是标准的缺陷,但事实确实如此。
您可以简单地模板std::uniform_int_distributionon unsigned short,并将其最小/最大范围设置为std::numeric_limits<unsigned char>::min()和std::numeric_limits<unsigned char>::max(),然后简单地将结果分配给unsigned char。
从标准:
在本第 26.5 条中,实例化模板的效果:
[...]
e) 具有名为的模板类型参数
IntType是未定义的,除非相应的模板参数是 cv-unqualified 并且是short,int,long,long long,unsigned short,unsigned int,unsigned long, 或 之一unsigned long long。§26.5.1.1 [rand.req.genl]
而且:
您应该使用std::mt19937来实际生成随机字节。 std::random_device可能会很慢,并且可能会产生您不需要的具有统计属性(即适用于密码学)的熵。
也就是说,您将需要为您的std::mt19937. 你可以用 astd::random_device和 a来做到这一点std::seed_seq。
请注意,如果您不使用 astd::seed_seq来播种您的std::mt19937,那么您std::mt19937的内部状态将留下许多许多零,因此需要很长时间才能“热身”。
有关“热身”的更多信息,请参见此处。
| 归档时间: |
|
| 查看次数: |
12675 次 |
| 最近记录: |