Random numbers
Cách dùng
hàm Random trong masm32.lib
Author: Benina
A-Lý thuyết:
Trước tiên ta
khai báo:
include
\masm32\m32lib\masm32.inc
includelib
\masm32\m32lib\masm32.lib
Sau đó ta có
thể dùng 2 hàm nrandom và nseed trong masm32.lib
-Hàm
nseed (seed=tạo hạt) kết hợp với hàm GetTickCount để kích
“bộ ngẫu nhiên” random
-Sau đó dùng
hàm nrandom để tạo ra 1 số ngẫu nhiên trong khỏang từ 0---
>some_value theo code sau:
invoke
GetTickCount
invoke nseed,
eax
invoke
nrandom, some_value ; gets pseudo-random number up to some_value.
Tra API
reference ta có:
Hàm: GetTickCount
Hàm GetTickCount
function tìm lại số mili giây đã trôi qua từ khi Windows khởi động.
DWORD
GetTickCount(VOID)
Tham số hàm:
Hàm này ko có tham số.
Giá trị trả về :
Nếu hàm này gọi thành công , giá trị
trả về là một số mili giây trôi qua từ khi Windows khởi động.
Remarks (nhận
xét):
Thời gian trôi qua được chứa trong một giá
trị DWORD. Dù vậy, thời gian sẽ quay lại zero
khi Windows đã chạy liên tục
trong 49.7 days.
Windows NT:
Nhận được thời gian trôi qua từ khi Windows khởi động bằng cách tìm
trong System Up Time counter
trong phần dữ liệu đã thực hiện (performance data) trong registry key HKEY_PERFORMANCE_DATA. Giá trị
trả về là một giá trị 8
byte.
Tra trong
Help masm32.lib ta có:
Hàm: nrandom
nrandom proc
base:DWORD
Mô tả:
Một thụat tóan Park Miller random algorithm được viết bởi Jaymeson Trudgen (NaN ) và được optimised bởi Rickey
Bowers Jr. (bitRAKE).
Tham số
1.
base xác định vùng giới hạn của số
random xuất ra từ Zero đến
base.
Giá trị trả về:
Số Random
với giới hạn từ zero đến "base" chứa trong EAX.
Chú thích:
Seed (gieo
hạt giống) cho thuật
tóan random algorithm là set
một biến GLOBAL trong một thủ
tục được tách ra đính kèm trong library module. Biến này là nrandom_seed và biến này sẽ được set với một số có kích
thước DWORD trước khi sử dụng
thuật tóan này.
B-Ví dụ:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include
\masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib
\masm32\lib\user32.lib
include \masm32\m32lib\masm32.inc
includelib
\masm32\m32lib\masm32.lib
.data
MsgBoxCaption db "Iczelion Tutorial No.00",0
sFormat db '%4i',0
buffer dd 128 dup (0)
.code
start:
invoke GetTickCount
invoke nseed,eax
invoke nrandom,500 ; eax return,
< some_value=500
invoke wsprintf,addr buffer,offset
sFormat, eax
invoke MessageBox, NULL, addr
buffer, addr MsgBoxCaption, MB_OK
invoke ExitProcess, NULL
end start
C. Source trong file nrand.asm:
Đây là source của hai hàm nrand và nseed trong file
nrand.asm:
;
«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
;
;
Park Miller random number algorithm.
;
;
Written by Jaymeson Trudgen (NaN )
;
Optimized by Rickey Bowers Jr. (bitRAKE)
;
;
«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat,
stdcall ; 32 bit memory model
option casemap :none ; case sensitive
.code
;
«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 4
nrandom PROC base:DWORD
mov eax, nrandom_seed
;
****************************************
test eax, 80000000h
jz @F
add eax, 7fffffffh
@@:
;
****************************************
xor edx, edx
mov ecx, 127773
div ecx
mov ecx, eax
mov eax, 16807
mul edx
mov edx, ecx
mov ecx, eax
mov eax, 2836
mul edx
sub ecx, eax
xor edx, edx
mov eax, ecx
mov nrandom_seed, ecx
div base
mov eax, edx
ret
nrandom ENDP
;
«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
nseed proc
TheSeed:DWORD
.data
nrandom_seed dd 12345678
.code
mov eax, TheSeed
mov nrandom_seed, eax
ret
nseed endp
;
«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end
C-Một số hàm random tham khảo thêm :
Hàm random một char
trong một chuổi char cho trước được viết bởi
diablo2oo2:
+Tạo file include như
sau:
RandomChar.inc
:
;----------------------------------------------------------------------------
;written by diablo2oo2
;example:
;invoke
RandomChar,chr$("ABCDEF0123456789") ; returns one of this char in eax
;----------------------------------------------------------------------------
RandomChar PROTO :DWORD
RAND32
PROTO :DWORD
InitRand32 PROTO
.data?
NaNRand dd
?
.code
RandomChar proc _string:DWORD
LOCAL _retvalue:BYTE
pushad
mov esi,_string
;---get lenght of
string---
xor ecx,ecx
.while byte ptr[esi+ecx]!=0
inc ecx
.endw
;---get random
char---
invoke InitRand32
invoke RAND32,eax
movzx eax,ax
cdq
idiv ecx
mov al,byte
ptr[esi+edx]
mov _retvalue,al
popad
movzx eax,_retvalue
ret
RandomChar endp
;----------------------------------------------------------------------------
; ----random
number generator by NaN ---
; ---(modified a bit to make it a procedure by
Exagone)---
;----------------------------------------------------------------------------
SWAP MACRO M1:REQ, M2:REQ
xor M1, M2
xor M2, M1
xor M1, M2
ENDM
InitRand32 proc
db 0fh,31h
shr eax, 2
add eax, 1
mov NaNRand, eax
ret
InitRand32 endp
RAND32 proc base:DWORD
;
Random number generator based on the Real time clock
;
and the Park, Miller random number algorithm
;
;
Coded by NaN for WIN32ASM
;
May 5, 2001
;
rev 2.
push ecx
push edx
mov eax, NaNRand
mov edx,0
mov ecx, 127773 ;q
div ecx ; eax == floor( seed / q)
; edx == remainder
SWAP eax, edx
push edx
mov ecx, 16807
mul ecx ; eax = mul of remainder * a
pop edx ; edx == floor of seed/q
SWAP eax, edx
push edx
mov ecx, 2836
mul ecx
pop edx ; edx == mull of rem * a
; eax == mull of seed/q * r
sub edx, eax
mov eax, edx
mov NaNRand, eax ; save next seed
mov ecx, base
mov edx, 0
div ecx
mov eax, edx
pop edx
pop ecx
ret
RAND32 endp
+Cách sử dụng hàm
RandomChar:
-Khai báo phần include : include randomplus.inc
-Khai báo một mảng các ký tự
trong .data mà ta cần random chỉ các ký tự đó thôi. Ví dụ:
sArrayRandom db
"ABCDEF0123456789",0
-Trong code ta gọi
hàm:
invoke RandomChar,offset
sArrayRandom
-Kết quả là eax chứa mã hex
của ký tự random
+Ví dụ:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include
\masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib
\masm32\lib\user32.lib
include randomChar.inc
.data
MsgBoxCaption db "Iczelion Tutorial No.00",0
sFormat db '%4c',0
buffer dd 128 dup (0)
sArrayRandom db
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",0
.code
start:
invoke RandomChar,offset
sArrayRandom
invoke wsprintf,addr buffer,offset
sFormat, eax
invoke MessageBox, NULL, addr
buffer, addr MsgBoxCaption, MB_OK
invoke ExitProcess, NULL
end start
;------------------------------------------------------------------------------
Source code:
Win32 386+
Random-Number-In-Range Generator. (Team vx 29a)
; Win32 386+
Random-Number-In-Range Generator.
;
; Most Win32 random number
generators I've come across so far were
; actually rather predictable, so here goes my attempt to code
a
; truely random one. It's small, simple and reasonably
fast.
;
.386
.MODEL FLAT
EXTRN GetTickCount:PROC
EXTRN ExitProcess:PROC
.DATA
Random_Seed DD
0
.CODE
START:
CALL GetTickCount ; Initialize random
seed.
MOV Random_Seed, EAX ; This can be
anything.
MOV EAX, 10 ; Returns a random
value
CALL Random_EAX ; between 0 and
9.
PUSH 0
CALL ExitProcess
; Entry: EAX ==
Max_Val.
; Return: EAX == Random
number between 0..Max_Val-1.
Random_EAX:
PUSH ECX ; Save registers that
get
PUSH EDX ;
changed.
PUSH EAX ; Save
Max_Val.
CALL GetTickCount ; Get random
value.
MOV ECX, Random_Seed ; Get random
seed.
ADD EAX, ECX ; Adjust random value
with
; random seed.
ROL ECX, 1 ; Adjust random
seed.
ADD ECX, 666h
MOV Random_Seed, ECX
; Perform CRC-32 on semi-random
number
; to
obtain a truely random number.
PUSH 32
POP ECX
CRC_Bit: SHR
EAX, 1 ; Bit is
set?
JNC Loop_CRC_Bit
XOR EAX, 0EDB88320h
Loop_CRC_Bit: LOOP
CRC_Bit ; Do all
32 bits.
POP ECX ; ECX =
Max_Val.
XOR EDX, EDX ; Divide truely random
value
DIV ECX ; by
Max_Val.
XCHG
EDX, EAX ;
Remainder is the
; random-in-range number.
OR EAX, EAX ; Test for
zero.
POP EDX
POP ECX
RETN
END START
HẾT TUT
Benina (10/11/2005)
Moded (26/9/2007)