Rnd: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
No edit summary |
mNo edit summary |
||
Line 3: | Line 3: | ||
==Description == | ==Description == | ||
Generates a random number within a range using the RtlGenRandom api. | Generates a random number within a range using the RtlGenRandom api. | ||
It can be used as is, or as a random seed generator for other functions, like http://nsis.sourceforge.net/Random. The Microsoft C Runtime Library makes use of this function in its implementation of "rand_s". | |||
== Example == | == Example == |
Revision as of 16:25, 7 December 2011
Author: Lloigor (talk, contrib) |
Description
Generates a random number within a range using the RtlGenRandom api.
It can be used as is, or as a random seed generator for other functions, like http://nsis.sourceforge.net/Random. The Microsoft C Runtime Library makes use of this function in its implementation of "rand_s".
Example
!define tempfile "$EXEDIR\test_output.txt" FileOpen $R0 "${tempfile}" "w" StrCpy $3 0 loop: IntOp $3 $3 + 1 ;-------------------------- ${Rnd} $0 -50000 50000 ;-------------------------- FileWrite $R0 "$0$\r$\n" IntCmp $3 1000 0 loop FileClose $R0 ExecWait 'notepad "${tempfile}"' Delete "${tempfile}"
Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Generate a random number using the RtlGenRandom api ;; P1 :out: Random number ;; P2 :in: Minimum value ;; P3 :in: Maximum value ;; min/max P2 and P3 values = -2 147 483 647 / 2 147 483 647 ;; max interval = 2 147 483 647 (31-bit) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !define Rnd "!insertmacro _Rnd" !macro _Rnd _RetVal_ _Min_ _Max_ Push "${_Max_}" Push "${_Min_}" Call Rnd Pop ${_RetVal_} !macroend Function Rnd Exch $0 ;; Min / return value Exch Exch $1 ;; Max / random value Push "$3" ;; Max - Min range Push "$4" ;; random value buffer IntOp $3 $1 - $0 IntOp $3 $3 + 1 System::Call '*(i) i .r4' System::Call 'advapi32::SystemFunction036(i r4, i 4)' ;; RtlGenRandom System::Call '*$4(i .r1)' System::Free $4 IntOp $1 $1 & 0x7FFFFFFF ;; no negative value for modulus operation IntOp $1 $1 % $3 ;; fit value within range IntOp $0 $1 + $0 ;; index with minimum value Pop $4 Pop $3 Pop $1 Exch $0 FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Generate a random 64-bit number using the RtlGenRandom api ;; P1 :out: Random number ;; P2 :in: Minimum value ;; P3 :in: Maximum value ;; min/max P2 and P3 values = -9 223 372 036 854 775 807 / 9 223 372 036 854 775 807 ;; max interval = 9 223 372 036 854 775 807 (63-bit) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !define Rnd64 "!insertmacro _Rnd64" !macro _Rnd64 _RetVal_ _Min_ _Max_ Push "${_Max_}" Push "${_Min_}" Call Rnd64 Pop ${_RetVal_} !macroend Function Rnd64 Exch $0 ;; Min / return value Exch Exch $1 ;; Max / random value Push "$3" ;; Max - Min range Push "$4" ;; random value buffer System::Int64Op $1 - $0 Pop $3 System::Int64Op $3 + 1 Pop $3 System::Call '*(l) i .r4' System::Call 'advapi32::SystemFunction036(i r4, i 8)' ;; RtlGenRandom System::Call '*$4(l .r1)' System::Free $4 System::Int64Op $1 & 0x7FFFFFFFFFFFFFFF ;; no negative value for modulus operation Pop $1 System::Int64Op $1 % $3 ;; fit value within range Pop $1 System::Int64Op $1 + $0 ;; index with minimum value Pop $0 Pop $4 Pop $3 Pop $1 Exch $0 FunctionEnd