摘要: random()函數和rand()函數都可以產生隨機數,但是,兩者的實現過程是不一樣的,在使用這兩個函數時總是會遇到一些疑問。該文結合實例分析了rand()函數產生隨機數的過程,對不同隨機函數的使用有一定的指導意義。
關鍵詞:C++語言; 隨機函數;隨機數
中圖分類號:TP312 文獻標識碼:A 文章編號:1009-3044(2015)34-0104-02
Abstract: random () function and rand () function can generate random numbers, but both the implementation process is not the same when using these two functions will always encounter some doubts. Examples of this paper analyzes the rand () function generates a random number process, the use of different random function has a certain significance.
Key words: C ++ language; random function; random numbers
在C語言中的隨機數函數是randomize()和random(),前者是產生隨機數的種子,而后者是根據前者生成的種子來產生隨機數。random()函數產生的隨機數是一種偽隨機數。在C++語言的開發工具中(例如DEV C++)已經無法使用randomize()函數參數隨機數了,取而代之的是rand()函數[1-3],接下來就分析一下rand()函數產生隨機數的實現原理。
1 產生隨機數的實例
C++語言編寫的產生隨機數的程序,如下代碼所示。
#include "stdlib.h"
#include
using namespace std;
int main()
{for(int i=1;i<=10;i++)
cout< return 0; } 程序運行后輸出10個整數,分別是: 41 18467 6334 26500 19169 15724 11478 29358 26962 24464 為了更加清晰的了解rand( )函數,可以通過工具逆向分析一下這個程序,逆向生成的主要代碼如下。 CALL DWORD PTRDS:[<&MSVCR90D.rand>] ;調用rand函數 MOV DWORD PTR SS:[EBP-8],EAX ;rand的返回值賦值保存給[EBP-8] MOV EAX,DWORD PTR SS:[EBP-8] PUSH EAX PUSH OFFSET Randomiz.??_C@_0BF@NKDDNMAK@>; ASCII " Random number = %d" CALL DWORD PTR DS:[<&MSVCR90D.printf>] 首先程序先調用rand函數,然后把返回值賦值給寄存器EAX,再把EAX返回的隨機數賦值給地址[EBP-8]保存,最后把EAX的值當做參數壓棧后在調用printf()函數[4]。這就是輸出模塊的底層實現了,由于我們探尋的是rand()的函數的實現原理,所以,接下來探討一下rand函數的內部實現。 2 rand函數的內部實現 rand函數的內部代碼如下: 54E33085 PUSH ECX 54E33086 CALL MSVCR90D._getptd ;調用_getptd函數 54E3308B MOV DWORD PTR SS:[EBP-4],EAX 54E3308E MOV EAX,DWORD PTR SS:[EBP-4] 54E33091 MOV ECX,DWORD PTR DS:[EAX+14] 54E33094 IMUL ECX,ECX,343FD ;帶符號數乘法指令 54E3309A ADD ECX,269EC3 ;加法 54E330A0 MOV EDX,DWORD PTR SS:[EBP-4] 54E330A3 MOV DWORD PTR DS:[EDX+14],ECX 54E330A6 MOV EAX,DWORD PTR SS:[EBP-4] 54E330A9 MOV EAX,DWORD PTR DS:[EAX+14] 54E330AC SHR EAX,10 ;邏輯右移 54E330AF AND EAX,7FFF ;和 54E330B4 MOV ESP,EBP 54E330B6 POP EBP 54E330B7 RETN 在rand( )函數的內部調用了一個未公開的函數_getptd(),無法得知_getptd( )函數的內部細節,不知道這個函數做了什么。但是,可以分析整個函數的代碼,并結合rand函數的外部代碼,可以看出_getptd( )函數的返回值并沒有被使用。……