# RC4: Pseudo Random Number Generator #
MODE RS = STRUCT([0:255]CHAR s, INT i, j);
OP MD = (INT j)INT: (j<256|j|MD (j-256));
PROC init = (STRING key)RS: ([0:255]CHAR s;
  FOR j FROM 0 TO 255 DO s[j] := REPR j OD;
  INT len = UPB key; INT j := 0;
  FOR i FROM 0 TO 255 DO CHAR t = s[i];
    j := MD (ABS t + j + ABS key[(i %* len) + 1]);
    s[i] := s[j]; s[j] := t OD; (s, 0, 0));
PROC n = (REF RS s)INT: (i OF s := MD(i OF s+1);
    CHAR a = (s OF s)[i OF s]; INT ai = ABS a;
    j OF s := MD (j OF s + ai); CHAR b = (s OF s)[j OF s];
    (s OF s)[i OF s] := b; (s OF s)[j OF s] := a;
    ABS((s OF s)[MD(ai + ABS b)]));

OP XOR = (CHAR a, b)CHAR: REPR ABS ((BIN ABS a) XOR (BIN ABS b));
##(1|
(RS s := init("Slouch"); TO 1048576 DO n(s) OD; TO 256 DO print(n(s)) OD),
(RS s := init("Slouch");
PROC nextrandom = REAL: (REAL x := 0; TO 7 DO x := 256*x + n(s) OD; x*(2.0**-56));
TO 20 DO print((nextrandom, newline)) OD;
(REAL x := 0, y := 0; TO 1000 DO REAL q=nextrandom; x +:= q; y +:= q*q OD;
print ((x, y)))),

(RS s := init("Seed stuff"); TO 1000 DO n(s) OD; TO 3 DO print(n(s)) OD)
# 83, 187, 241 #,

(RS s := init("Philosophical"); TO 1048576 DO n(s) OD; TO 30 DO  print(n(s)) OD))