Rnd
From NSIS Wiki
Jump to navigationJump to search
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 (RtlGenRandom) 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}"
Function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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 range = 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 ;; calculate range IntOp $3 $3 + 1 System::Call '*(l) i .r4' System::Call 'advapi32::SystemFunction036(i r4, i 4)' ;; RtlGenRandom System::Call '*$4(l .r1)' System::Free $4 ;; fit value within range System::Int64Op $1 * $3 Pop $3 System::Int64Op $3 / 0xFFFFFFFF Pop $3 IntOp $0 $3 + $0 ;; index with minimum value Pop $4 Pop $3 Pop $1 Exch $0 FunctionEnd