国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

C和C++語言產(chǎn)生隨機(jī)數(shù)的過程分析

2016-03-07 12:56周建儒
電腦知識(shí)與技術(shù) 2015年34期
關(guān)鍵詞:語言

摘要: random()函數(shù)和rand()函數(shù)都可以產(chǎn)生隨機(jī)數(shù),但是,兩者的實(shí)現(xiàn)過程是不一樣的,在使用這兩個(gè)函數(shù)時(shí)總是會(huì)遇到一些疑問。該文結(jié)合實(shí)例分析了rand()函數(shù)產(chǎn)生隨機(jī)數(shù)的過程,對(duì)不同隨機(jī)函數(shù)的使用有一定的指導(dǎo)意義。

關(guān)鍵詞:C++語言; 隨機(jī)函數(shù);隨機(jī)數(shù)

中圖分類號(hào):TP312 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):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語言中的隨機(jī)數(shù)函數(shù)是randomize()和random(),前者是產(chǎn)生隨機(jī)數(shù)的種子,而后者是根據(jù)前者生成的種子來產(chǎn)生隨機(jī)數(shù)。random()函數(shù)產(chǎn)生的隨機(jī)數(shù)是一種偽隨機(jī)數(shù)。在C++語言的開發(fā)工具中(例如DEV C++)已經(jīng)無法使用randomize()函數(shù)參數(shù)隨機(jī)數(shù)了,取而代之的是rand()函數(shù)[1-3],接下來就分析一下rand()函數(shù)產(chǎn)生隨機(jī)數(shù)的實(shí)現(xiàn)原理。

1 產(chǎn)生隨機(jī)數(shù)的實(shí)例

C++語言編寫的產(chǎn)生隨機(jī)數(shù)的程序,如下代碼所示。

#include "stdlib.h"

#include

using namespace std;

int main()

{for(int i=1;i<=10;i++)

cout<

return 0; }

程序運(yùn)行后輸出10個(gè)整數(shù),分別是:

41 18467 6334 26500 19169 15724 11478 29358 26962 24464

為了更加清晰的了解rand( )函數(shù),可以通過工具逆向分析一下這個(gè)程序,逆向生成的主要代碼如下。

CALL DWORD PTRDS:[<&MSVCR90D.rand>] ;調(diào)用rand函數(shù)

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>]

首先程序先調(diào)用rand函數(shù),然后把返回值賦值給寄存器EAX,再把EAX返回的隨機(jī)數(shù)賦值給地址[EBP-8]保存,最后把EAX的值當(dāng)做參數(shù)壓棧后在調(diào)用printf()函數(shù)[4]。這就是輸出模塊的底層實(shí)現(xiàn)了,由于我們探尋的是rand()的函數(shù)的實(shí)現(xiàn)原理,所以,接下來探討一下rand函數(shù)的內(nèi)部實(shí)現(xiàn)。

2 rand函數(shù)的內(nèi)部實(shí)現(xiàn)

rand函數(shù)的內(nèi)部代碼如下:

54E33085 PUSH ECX

54E33086 CALL MSVCR90D._getptd ;調(diào)用_getptd函數(shù)

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 ;帶符號(hào)數(shù)乘法指令

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( )函數(shù)的內(nèi)部調(diào)用了一個(gè)未公開的函數(shù)_getptd(),無法得知_getptd( )函數(shù)的內(nèi)部細(xì)節(jié),不知道這個(gè)函數(shù)做了什么。但是,可以分析整個(gè)函數(shù)的代碼,并結(jié)合rand函數(shù)的外部代碼,可以看出_getptd( )函數(shù)的返回值并沒有被使用。同時(shí),變量[EAX+14]這個(gè)值引起了高度關(guān)注,可以深入分析變量[EAX+14]得出關(guān)于_getptd( )函數(shù)的信息[5]。可以借助OllyDbg動(dòng)態(tài)反匯編工具看一看[EAX+14]的初始值,反匯編代碼如下所示。

5E0C308B 8945 FC MOV DWORD PTR SS:[EBP-4], EAX

5E0C308E 8B45 FC MOV EAX, DWORD PTR SS:[EBP-4], EAX

5E0C3091 8B4814 MOV ECX, DWORD PTR DS:[EAX+14]

5E0C3094 69C9 FD430300 IMUL ECX, ECX, 343FD

5E0C309A 81C1 C29E2600 ADD ECX, 269EC3

5E0C30A0 8B55 FC MOV EDX, DWORD PTR SS:[EBP-4]

5E0C30A3 894A 14 MOV DWORD PTR DS:[EDX+14], ECX

5E0C30A6 8B45 FC MOV EAX, DWORD PTR SS:[EBP-4]

5E0C30A9 8B40 14 MOV EAX, DWORD PTR DS:[EAX+14]

通過反編譯后的結(jié)果,可以看出原來[EAX+14]指向的地址是005A0814,而它的值是0x00000001,也就相當(dāng)于十進(jìn)制數(shù)1。知道了這個(gè)關(guān)鍵點(diǎn),現(xiàn)在可以把rand( )函數(shù)的內(nèi)部代碼簡化一下,如下代碼所示。

MOV ECX, DWORD PTR DS:[EAX+14] ;ECX=000000001

IMUL ECX, ECX,343FD ;帶符號(hào)數(shù)乘法指令

ADD ECX, 269EC3 ;加法

MOV DWORD PTR DS:[EDX+14],ECX

MOV EAX, DWORD PTR DS:[EAX+14]

SHR EAX, 10 ;邏輯右移

AND EAX, 7FFF ;和

MOV ESP, EBP

POP EBP

RETN

rand()通過把[EAX+14]地址的值賦值給ECX,然后再使用帶符號(hào)數(shù)乘法指令和加法指令進(jìn)行運(yùn)算,最后把計(jì)算的結(jié)果重新賦值給[EAX+14],這樣做是覆蓋掉[EAX+14]原先的值00000001,然后在重新計(jì)算的[EAX+14]的值賦值給EAX,EAX在進(jìn)行邏輯右移和和操作[6],通過這些復(fù)雜的運(yùn)算,rand最終生成了一個(gè)隨機(jī)數(shù)。

3 自定義隨機(jī)函數(shù)

經(jīng)過分析,比較清楚的了解了rand( )函數(shù)的實(shí)現(xiàn)原理,此時(shí),就可以自己編寫一個(gè)產(chǎn)生隨機(jī)數(shù)的函數(shù)了,具體實(shí)現(xiàn)代碼如下所示。

#include

#include

int _tmain(int argc, _TCHAR* argv[])

{

int tnum = 0x00000001;

int Rnum = 0;

while(1){

_asm

{

pushad

mov ecx, tnum

imul ecx,ecx,343fdH

add ecx,369ec3H

mov tnum,ecx

mov eax,ecx

shr eax,10H

and eax,7fffH

mov Rnum,eax

popad

}

printf(" %d\t",Rnum);

system(“pause”);

}

return 0;

}

編譯運(yùn)行此程序,輸出的結(jié)果與rand函數(shù)運(yùn)行的結(jié)果是一樣的。

4 結(jié)束語

random()、rand()函數(shù)都可以產(chǎn)生隨機(jī)數(shù),但是在不同的編程語言及開發(fā)工具中的使用是有差別的。random函數(shù)不是ANSI C標(biāo)準(zhǔn),不能在gcc,vc等編譯器下編譯通過。本文分析了rand函數(shù)的內(nèi)部實(shí)現(xiàn)原理,分析了產(chǎn)生隨機(jī)數(shù)的過程,拓展了初學(xué)習(xí)C語言同學(xué)的知識(shí)視野,也激發(fā)他們探索C語言奧妙的興趣。

參考文獻(xiàn):

[1] 周建儒.C語言中邏輯關(guān)系與邏輯運(yùn)算的分析[J].電子測試,2012(22):38-39.

[2] 周志德,候正昌.C++程序設(shè)計(jì)[M].北京:電子工業(yè)出版社,2005.

[3] ??藸枺瑒⒆谔?C++編程思想[M].北京:機(jī)械工業(yè)出版社,2012.

[4] 趙鳳芝.C語言程序設(shè)計(jì)能力教程[M].北京:中國鐵道出版社,2006.

[5] 劉金魁.C語言程序設(shè)計(jì)基礎(chǔ)[M].北京:中國鐵道出版社,2014.

[6] 田美艷.計(jì)算機(jī)中C語言的應(yīng)用特點(diǎn)分析[J].電子制作,2015(4):87.

猜你喜歡
語言
詩之新,以語言創(chuàng)造為基
(n,k)-語言及左-(n,k)-語言的一些性質(zhì)
語言是刀
讓語言描寫搖曳多姿
多向度交往對(duì)語言磨蝕的補(bǔ)正之道
累積動(dòng)態(tài)分析下的同聲傳譯語言壓縮
日常語言與播音語言
語言技能退化與語言瀕危
我有我語言
論語言的“得體”
康定县| 东乌珠穆沁旗| 莲花县| 喀喇| 瑞丽市| 石台县| 谢通门县| 夏邑县| 渭南市| 郯城县| 班戈县| 吉林市| 资源县| 洛扎县| 离岛区| 东宁县| 宁津县| 竹山县| 蒲江县| 三江| 连南| 板桥市| 彰武县| 麦盖提县| 巴青县| 柘城县| 七台河市| 东乡| 秭归县| 舒兰市| 县级市| 廊坊市| 陆河县| 会宁县| 华容县| 西丰县| 筠连县| 伊宁市| 金塔县| 泸水县| 北海市|