-
Notifications
You must be signed in to change notification settings - Fork 1
/
rand.clj
42 lines (37 loc) · 1.23 KB
/
rand.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(ns uniformity.internals.java.rand
(:import java.security.SecureRandom))
;; Performance notes:
;;
;; After benchmarking various algorithm options for SecureRandom with OpenJDK on Linux,
;; I found negligible differences between mean execution time for e.g. nextInt().
;; It seems reasonable to just allow the default constructor to choose one.
;;
;; SecureRandom is thread-safe, however there is a possibility that heavily
;; calling on an instance from many threads could lead to a performance penalty.
;; If this does turn out to be an issue, we could use ThreadLocal<SecureRandom>.
(defonce sec-rand (SecureRandom.))
(defn rand-bytes
^bytes
[^long n]
{:pre [(> n 0)]
:post [(= n (count %))]}
(let [bs (byte-array n)]
(.nextBytes sec-rand bs)
bs))
(defn rand-int32
([] (rand-int32 (Math/pow 2 31)))
([bound]
{:pre [(<= bound (Math/pow 2 31))
(> bound 0)]
:post [(< % bound)]}
(.nextInt sec-rand bound))
([lower upper]
{:pre [(> upper lower)
(> lower (Math/pow -2 31))]
:post [(>= % lower)]}
(let [bound (- upper lower)
result (rand-int32 bound)]
(+ result lower))))
(defn rand-uuid []
;; randomUUID uses a CSPRNG, according to Java docs
(java.util.UUID/randomUUID))