1 (* Copyright (C
) 1999-2005 Henry Cejtin
, Matthew Fluet
, Suresh
2 * Jagannathan
, and Stephen Weeks
.
3 * Copyright (C
) 1997-2000 NEC Research Institute
.
5 * MLton is released under a BSD
-style license
.
6 * See the file MLton
-LICENSE for details
.
9 structure MLtonRandom
: MLTON_RANDOM
=
11 (* Uses
/dev
/random
and /dev
/urandom to get a random
word.
12 * If they can
't be read from
, return NONE
.
15 fun make (file
, name
) =
17 val buf
= Word8Array
.array (4, 0w0
)
25 openf (file
, O_RDONLY
, O
.flags
[])
29 val n
= Posix
.IO
.readArr (fd
,
31 (buf
, 4 - rem
, SOME rem
))
33 then (Posix
.IO
.close fd
; raise Fail name
)
42 val _
= Posix
.IO
.close fd
44 SOME (Word.fromLarge (PackWord32Little
.subArr (buf
, 0)))
46 handle OS
.SysErr _
=> NONE
)
49 val seed
= make ("/dev/random", "Random.seed")
50 val useed
= make ("/dev/urandom", "Random.useed")
55 val seed
: word ref
= ref
0w13
57 (* From page
284 of Numerical Recipes
in C
. *)
60 val res
= 0w1664525
* !seed
+ 0w1013904223
66 fun srand (w
: word): unit
= seed
:= w
71 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
72 val numChars
= String.size chars
75 val numChars
= IntInf
.fromInt numChars
76 fun loop (i
: IntInf
.int, c
: int): int =
77 if IntInf
.< (i
, numChars
)
79 else loop (IntInf
.div (i
, numChars
), c
+ 1)
81 loop (IntInf
.pow (2, Word.wordSize
), 0)
83 val r
: word ref
= ref
0w0
84 val count
: int ref
= ref refresh
85 val numChars
= Word.fromInt numChars
87 fun alphaNumChar (): char
=
90 val _
= if n
= refresh
95 val c
= String.sub (chars
, Word.toInt (Word.mod (w
, numChars
)))
96 val _
= r
:= Word.div (w
, numChars
)
102 fun alphaNumString (length
: int): string =
103 String.tabulate (length
, fn _
=> alphaNumChar ())