根据我对标准的阅读,如果使用软件引擎,random_device::entropy()
应返回0.0。但是,在VS2010中,它返回32.0,这在我的理解中要求硬件产生非确定性随机数。
VS2010的random_device
如何生成数字序列?
答案 0 :(得分:22)
根据Hans Passant在此问题上留下的评论,random_device
使用advapi32:SystemFunction036
,根据MSDN,RtlGenRandom
是random_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,但似乎还没有使用它。