mIRC Home    About    Download    Register    News    Help

Topic Options
#200666 - 09/06/08 04:51 PM $rand is not always random?
Brax Offline
Vogon poet

Registered: 26/01/05
Posts: 186
I couldnt find at the moment anything related to this problem so here goes:

Here is a piece of code...
Code:
alias doRandom {
  var %y = $1
  var %i = 1
  while (%i <= %y) {
    if ($r(1,4) == 1) var %x = $r(a,z) 
    if ($r(1,4) == 2) var %x = $r(A,Z)
    if ($r(1,4) == 3) var %x = $r(0,9)
    if ($r(1,4) == 4) var %x = $r(a,Z)
    var %res = %res $+ %x
    inc %i
  }
  echo -a %res
}


And here is 5 lines of output via /doRandom 50
(Colors added manually of course)

_111]sXX^77Z3_g\U333000oooooqqZZccVVIIIUNNVV[Ea`_J
TTTZZQ666X2222Z8_8[aa6RRxz6^tZ44aa0Y]\\v5bQc555]]
pQoCZ``]88\````7VYGemmGGn_b3355555Dy8^V]]cAAAAa7B\
t\^^^^uaa74v3394[8]]Z5[[[\9rrxxxxxgU````ZXXX^^^^4^
^^^3aU555hhe77772\\^\FFZlD__YX667PKkkkkkVi`51]2ZZ


And the list goes on pretty much like this.... the longer the line is the worse it gets....

For example with 100 chars:
r^``````44oaaaaan4rZ\Ca]]]]]]5t77^Y0000000a\\\]7\qq8888555aa22^558\\J55``12_`jZ62220022[[[[``mmmUUUUUk[[[[6^6Sxxp7`Ygg22aaaaUU333``1111174XXXf22EEEQe6

So the question is: what happened with random?
Why it generates so much identical sequences?

From Wikipedia:
Quote:
Randomness versus unpredictability

Randomness is an objective property. Nevertheless, what appears random to one observer may not appear random to another observer.
/../


Is that the reason or is mIRC (or me) messing something up?
_________________________
echo -a $signature

Top
#200668 - 09/06/08 05:24 PM Re: $rand is not always random? [Re: Brax]
argv0 Offline
Planetary brain

Registered: 13/10/03
Posts: 3918
Loc: Montreal, QC, Canada
I think the wikipedia article is right.

Your test is not accurate anyway, because it uses too small an entropy value to actually give random results.

A fairer illustration of $rand's true randomness would be an unbiased test of the raw $rand results-- here is an example alias:

Code:
randnumbers { 
  var %i = 1, %out, %reps = 0, %n = $iif($1,$1,100)
  var %max = $iif($2,$2,$calc(%n * 10))
  while (%i < %n) {
    var %x = $rand(1,%max)
    if ($istok(%out,%x,32)) inc %reps
    %out = %out %x
    inc %i
  }
  echo -a %reps collisions of %n numbers (ratio $calc(%reps / %n * 100) $+ % $+ ): %out
}


Running the alias 100 times on a 1000 number spread ($rand(1,100)) gets me:

6 collisions of 100 numbers (ratio 6%): 908 849 246 70 245 168 113 78 856 449 931 706 644 619 384 703 943 127 705 502 912 331 374 91 56 26 119 491 446 690 880 702 60 146 913 543 862 855 247 117 173 222 674 100 85 408 519 142 809 839 572 702 942 213 410 965 18 568 227 601 713 169 172 646 908 992 58 797 379 647 113 768 271 394 846 745 36 880 214 510 396 100 586 486 351 197 985 610 659 231 742 360 477 634 861 121 290 78 136

Those are some fairly normalized results. Obviously if we bring down the spread (as your example did heavily), we can see the ratio go up. If we run the same alias 100 times with a spread of 100 numbers we get:

33 collisions of 100 numbers (ratio 33%): 94 15 30 38 16 12 80 40 8 19 80 3 66 86 84 52 71 56 49 55 41 16 36 35 76 53 8 42 90 2 62 43 46 35 53 58 84 10 83 42 78 17 58 5 41 57 21 48 51 46 15 12 96 17 32 6 67 60 1 88 41 17 62 61 80 15 24 13 52 6 89 38 5 8 58 50 1 57 41 54 59 92 62 26 80 37 11 72 27 69 30 22 24 63 83 33 8 4 20

This is also fairly normalized given that there are 100 slots for 100 selections.

I did you the favour of doing some extra research on the calculation of "randomness" and came across this utility that performs (among other things) a Chi-squared test on a randomly generated resultset to illustrate its "randomness". To quote the url,

Quote:
The chi-square test is the most commonly used test for the randomness of data, and is extremely sensitive to errors in pseudorandom sequence generators. ... We interpret the percentage as the degree to which the sequence tested is suspected of being non-random. If the percentage is greater than 99% or less than 1%, the sequence is almost certainly not random. If the percentage is between 99% and 95% or between 1% and 5%, the sequence is suspect. Percentages between 90% and 95% and 5% and 10% indicate the sequence is “almost suspect”.


Interestingly enough, the results from mIRC are very impressive:

Code:
Entropy = 7.996480 bits per byte.

Optimum compression would reduce the size
of this 50001 byte file by 0 percent.

Chi square distribution for 50001 samples is 245.14, and randomly
would exceed this value 66.01 percent of the times.

Arithmetic mean value of data bytes is 127.3520 (127.5 = random).
Monte Carlo value for Pi is 3.163806552 (error 0.71 percent).
Serial correlation coefficient is -0.003063 (totally uncorrelated = 0.0).


You'll notice that unix's rand() function returns a % value of 99.99 or above, meaning it is "unacceptably non-random" according to the site. Our results are 66%, which are far more impressive. In fact:

Quote:
Contrast both of these software generators with the chi-square result of a genuine random sequence created by timing radioactive decay events.

Chi square distribution for 500000 samples is 249.51, and randomly would exceed this value 40.98 percent of the times.


So ~60% is pretty damn random.

For reference, the code I used was:

Code:
ent { 
  var %i = 1, %n = $iif($1,$1,50000), %max = 255
  while (%i <= %n) {
    bset &b %i $rand(0,%max)
    inc %i
  }
  bwrite rand.ent 1 -1 &b
}


The rand.ent file was then fed into ent.exe to get the above output.
_________________________
- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"

Top
#200671 - 09/06/08 06:23 PM Re: $rand is not always random? [Re: Brax]
Horstl Offline
Hoopy frood

Registered: 03/11/06
Posts: 1559
Loc: Germany
Code:
  while (%i <= %y) {
    if ($r(1,4) == 1) var %x = $r(a,z) 
    if ($r(1,4) == 2) var %x = $r(A,Z)
    if ($r(1,4) == 3) var %x = $r(0,9)
    if ($r(1,4) == 4) var %x = $r(a,Z)
    var %res = %res $+ %x
    inc %i
  }
Your code is picking a new random number for each if-random-number-is something-condition, thus it is "likely" (a 0.31 to 1 chance) that each if-condition is not met, and the "old" %x will be added to %res.
compare your code to:
Code:
  while (%i <= %y) {
  var %r = $r(1,4)
    if (%r == 1) var %x = $r(a,z) 
    elseif (%r == 2) var %x = $r(A,Z)
    elseif (%r == 3) var %x = $r(0,9)
    else var %x = $r(a,Z)
    var %res = %res $+ %x
    inc %i
  }

Top
#200672 - 09/06/08 06:31 PM Re: $rand is not always random? [Re: argv0]
Brax Offline
Vogon poet

Registered: 26/01/05
Posts: 186
-Removed long rant-

Re: Horstl
Thanks, now i see what went wrong...
Indeed generating new $r(1,4) on each IF clause will mess it up...
Who knows how i missed this one...

----
Conclusion, Random IS RANDOM after all.
As long as i write my scrips while im awake blush


Edited by Brax (09/06/08 06:40 PM)
_________________________
echo -a $signature

Top
#200673 - 09/06/08 06:36 PM Re: $rand is not always random? [Re: Brax]
Horstl Offline
Hoopy frood

Registered: 03/11/06
Posts: 1559
Loc: Germany
same pitfall laugh

Top
#200675 - 09/06/08 06:42 PM Re: $rand is not always random? [Re: Horstl]
Brax Offline
Vogon poet

Registered: 26/01/05
Posts: 186
I was writing it down when you were posting your reply... smile

But well it all works now as i wanted it to be. Thanks
_________________________
echo -a $signature

Top
#211226 - 08/04/09 04:51 AM Re: $rand is not always random? [Re: Horstl]
DragonRyder Offline
Ameglian cow

Registered: 25/08/06
Posts: 31
Loc: OH, USA
using your example of:

Quote:
while (%i <= %y) {
var %r = $r(1,4)
if (%r == 1) var %x = $r(a,z)
elseif (%r == 2) var %x = $r(A,Z)
elseif (%r == 3) var %x = $r(0,9)
else var %x = $r(a,Z)
var %res = %res $+ %x
inc %i
}


how can i fix this little thing i put in my Popups:

Code:
.·UserNick: //timer $+ $rand(a,z) $+ $rand(1,9) $+ $rand(a,z) $+ $rand(1,9) 1 0 //svsnick $$* PantyHose- $+ $rand(1,9) $+ $rand(1,9) $+ $rand(1,9) $+ $rand(1,9) 0


this way i can highlight 1 to 100 nicks @ one time - and click UserNick and use my uline to svsnick their nicks into something else

yes i own the network i am using this on adn no it aint a war thing either - just something i do to give some laughs by changing all my friends nicks

Top
#211227 - 08/04/09 05:53 AM Re: $rand is not always random? [Re: DragonRyder]
Horstl Offline
Hoopy frood

Registered: 03/11/06
Posts: 1559
Loc: Germany
Using another method (aliased command with a while loop instead of the $* loop), this should allow you to mass-svsnick up to 999 users. Note that it's a remote script.

After selecting the nicks in the nicklist and click on "RandomNick", you'll be prompted for a nick prefix.
Every user will be svsnicked to "<chosenprefix>-<3-digit random number>. The script ensures no number is issued twice.
It doesn't use any timers, though this shouldn't be a big problem as long as you're olined wink

Code:
menu nicklist {
  ; show this popup only if 1) you're olined (usermode o) and 2) one to 999 nicks are selected in the nicklist
  ; if you don't like the o-line check, simply remove the "(o isin $usermode) &&"
  $iif((o isin $usermode) && ($snick($active,0) isnum 1-999),·RandomNick $v1 users) : { randnicks $0 }
}


alias -l randnicks {

  ; set %n to total number of selected nicks; ask for nick prefix ($gettok ensures you don't try to use spaces here)
  ; if you don't like the input prompt, just hard-code it here
  var %n =  $1, %prefix = $$gettok($input(What prefix shall the new nicks have?,eog,Mass-svsnick of %n selected user(s)),1,32)

  ; loop selected nicks (last to first)
  while (%n > 0) {

    ; draw a random 3-digit number (zeropadding low numbers)
    var %nicknr = $base($rand(1,999),10,10,3)

    ; this number hasn't been used so far
    if (!$var($+(%,randnick.,%nicknr),1).local) {

      ; set a local variable to mark this number as used
      var % $+ randnick. $+ %nicknr

      ; issue the svsnick command ( $snick($active,%n) is the currently processed nick )
      .msg operserv SVSNICK $snick($active,%n) $+(%prefix,-,%nicknr)

      ; proceed with next nick
      dec %n
    }
  }
}


Edit: fixed .local check at $var

Top