如何利用CPU生成随机数

最近碰到一个问题,就是在没有函数库或者API支持的情况下怎么生成随机数。

请教了一下别人,发现对于X86处理器来说,处理器的指令集里面就有生成随机数的指令--RDRAND,该指令利用的是x86 CPU上自带的随机数生成器,对于Intel x86处理器来说,该指令从Ivy Bridge开始支持,而AMD则从2015年起也添加了对这个指令的支持,所以老一点的处理器可能没法支持这个指令。

因为没有API,所以只能自己通过汇编调用该指令生成随机数,但是在执行的过程中发现,编译器没法识别该指令。所以只能用最简单粗暴的方式来实现,直接定义十六进制的指令,测试了一下,果然可以生成随机数,没有把程序搞挂掉。


GenerateRandomNumber PROC

    mov     rax, 0
    db 048h, 00Fh, 0C7h, 0F0h    ; invoke the RDRAND instruction to generate
                                ; the random number into eax
    ret
GenerateRandomNumber endp

根据函数调用的堆栈处理规则,rax/eax是被存放函数返回值的,在这个程序里面只有rax/eax这个寄存器被改变了,所以这里不需要对其他寄存器做任何操作,直接返回就行了。这个应该是最快的随机数生成方式,因为利用CPU的硬件资源直接调用CPU的一条指令,加上几条辅助的指令就行了。

个人认为现在处理器慢慢自带随机数生成器的一个主要原因是安全,因为很都加密算法或者其他类似的算法都需要用到随机数序列。对于x86处理器来说,其实可以通过CPUID指令去查看CPU是否支持RDRAND这个指令,如果支持的话,当执行CPUID (EAX=0x1)后,ECX的 bit30 就会被置起来。


顺便查找了一下ARM处理器是否有类似的随机数生成指令,目前来看还没有找到,可能是因为ARM追求的是精简指令集,所以暂时没有将类似的指令添加进去,但是个人觉得以后应该会添加进去,或者可能协处理器会添加进去,毕竟现在用到随机数序列的场合还是很多的。

你可能感兴趣的:(编程技巧,随机数生成,随机数,x86,CPU)