在VS2010中实现random_device?

时间:2012-03-03 19:56:42

标签: c++ visual-studio-2010 random c++11

根据我对标准的阅读,如果使用软件引擎,random_device::entropy()应返回0.0。但是,在VS2010中,它返回32.0,这在我的理解中要求硬件产生非确定性随机数。

VS2010的random_device如何生成数字序列?

2 个答案:

答案 0 :(得分:22)

根据Hans Passant在此问题上留下的评论,random_device使用advapi32:SystemFunction036,根据MSDN,RtlGenRandomrandom_device::operator()()的别名。这由VC ++ 2010提供的运行时库源验证:

<random>中的

_Random_device() // in xrngdev.cpp rand_s() // in rand_s.c RtlGenRandom()/SystemFunction036() // in advapi32.dll 调用以下函数链:

RtlGenRandom

根据Michael Howard在他的一篇博客文章"Cryptographically Secure Random number on Windows without using CryptoAPI"上留下的评论,{{1}}使用以下内容:

  

RNG按照FIPS 186-2附录3.1中的规定生成SHA-1   作为G功能。来自熵:

     
      
  • 当前进程ID(GetCurrentProcessID)。

  •   
  • 当前线程ID(GetCurrentThreadID)。

  •   
  • 自开机以来的刻度(GetTickCount)。

  •   
  • 当前时间(GetLocalTime)。

  •   
  • 各种高精度性能计数器(QueryPerformanceCounter)。

  •   
  • 用户环境块的MD4哈希值,包括用户名,计算机名和搜索路径。 MD4是一种散列算法   从输入数据创建128位消息摘要以验证数据   完整性。

  •   
  • 高精度内部CPU计数器,例如RDTSC,RDMSR,RDPMC

  •   
  • 低级系统信息:空闲处理时间,Io读取传输计数,I / O写入传输计数,I / O其他传输计数,I / O读取   操作计数,I / O写操作计数,I / O其他操作计数,   可用页面,承诺页面,提交限制,峰值承诺,页面   故障计数,写入计数复制,转换计数,高速缓存转换   计数,需求零计数,页面读取计数,页面读取I / O计数,缓存   读取计数,高速缓存I / O计数,脏页写入计数,脏写入I / O.   计数,映射页写入计数,映射写入I / O计数,分页池   页面,非分页池页面,分页池分配空间,分页池   自由空间,非分页池分配空间,非分页池自由空间,   免费系统页面表条目,驻留系统代码页,总系统   驱动程序页面,总系统代码页,非分页池旁视命中,   分页池旁视命中,可用分页池页面,驻留系统   缓存页面,驻留页面缓冲页面,驻留系统驱动程序页面,   高速缓存管理器快速读取,无等待,高速缓存管理器快速读取   等待,缓存管理器快速读取资源未命中,缓存管理器快速读取   不可能,高速缓存管理器快速存储器描述符列表读取否   等待,缓存管理器快速内存描述符列表读取等待,缓存   管理器快速内存描述符列表读取资源丢失,缓存   管理器快速内存描述符列表读取不可能,缓存管理器   无等待映射数据,高速缓存管理器使用等待映射数据,高速缓存管理器   没有等待错过的地图数据,缓存管理器映射数据等待错过,缓存   管理器引脚映射数据计数,高速缓存管理器无等待引脚读取,   高速缓存管理器引脚读取等待,高速缓存管理器引脚读取无等待   Miss,Cache manager Pin-Read Wait Miss,Cache manager Copy-Read with   无等待,高速缓存管理器Copy-Read with Wait,高速缓存管理器Copy-Read   没有等待错过,缓存管理器复制 - 读取等待错过,缓存   管理器内存描述符列表无等待读取,高速缓存管理器内存   描述符列表读取等待,高速缓存管理器内存描述符列表   读取无等待错过,高速缓存管理器内存描述符列表读取   Wait Miss,缓存管理器预读IO,缓存管理器Lazy-Write IOs,   缓存管理器Lazy-Write Pages,Cache manager Data Flushes,Cache   管理器数据页面,上下文切换,一级转换缓冲区   填充,二级转换缓冲区填充和系统调用。

  •   
  • 系统异常信息,包括对齐修正计数,异常调度计数,浮动仿真计数和字节字   仿真计数。

  •   
  • 系统旁视信息包括当前深度,最大深度,总分配,分配未命中,总免费,免费未命中,   类型,标记和大小。

  •   
  • 系统中断信息,包括上下文切换,延迟过程调用计数,延迟过程调用率,时间   增量,延迟过程调用旁路计数和异步   程序呼叫旁路计数。

  •   
  • 系统进程信息,包括下一个输入偏移量,线程数,创建时间,用户时间,内核时间,图像名称,基数   优先级,唯一进程ID,从唯一进程ID继承,句柄   计数,会话ID,页面目录库,峰值虚拟大小,虚拟   尺寸,页面错误计数,峰值工作集大小,工作集大小,配额   峰值分页池使用情况,配额分页池使用情况,配额峰值非分页   池使用,配额非分页池使用,页面文件使用,峰值页面   文件用法,专用页数,读操作计数,写操作   计数,其他操作计数,读取传输计数,写入传输   计数和其他转移计数。

  •   

编写安全代码的第8章第2版中有完整的解释(包括图表)。

答案 1 :(得分:2)

也许这是一个错误,也许不是。但它确实看起来很刻意。来自Microsoft的own documentation

  

该类描述了随机数的来源,最好来自a   非确定性外部设备。 在此实现中的值   默认生成的不是非确定性的。它们是统一的   分布在封闭范围[0,65535]。

来自C ++ 11标准,random_device上的第26.5.6.6节:

  

result_type operator()();

     

返回:非确定性随机值,   均匀分布在min()和max()之间,包括在内。它是   实现 - 定义了如何生成这些值。

严格阅读标准,他们不能从entropy()返回0以外的任何内容。也许他们计划有一天改进实施,并试图让它现在做一些合理的事情。他们确实有一个API调用来生成cryptographically secure random numbers,但似乎还没有使用它。