forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
randomdevice.jl
77 lines (70 loc) · 2.22 KB
/
randomdevice.jl
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# This file is a part of Julia. License is MIT: https://julialang.org/license
# This file contains the minimal support of RandomDevice for Base's own usage.
# The actual RandomDevice type that makes use of this infrastructure is defined
# in the Random stdlib.
module DevRandomState
if !Sys.iswindows()
mutable struct FileRef
@atomic file::Union{IOStream, Nothing}
end
const DEV_RANDOM = FileRef(nothing)
const DEV_URANDOM = FileRef(nothing)
end
function __init__()
if !Sys.iswindows()
@atomic DEV_RANDOM.file = nothing
@atomic DEV_URANDOM.file = nothing
end
end
end
if Sys.iswindows()
function RtlGenRandom!(A::Union{Array, Ref})
Base.windowserror("SystemFunction036 (RtlGenRandom)", 0 == ccall(
(:SystemFunction036, :Advapi32), stdcall, UInt8, (Ptr{Cvoid}, UInt32),
A, sizeof(A)))
end
# Manually implemented to work without the Random machinery
function _rand_uint()
r = Ref{Cuint}()
RtlGenRandom!(r)
return r[]
end
else # !windows
function _get_dev_random_fd(unlimited::Bool)
ref = unlimited ? DevRandomState.DEV_URANDOM : DevRandomState.DEV_RANDOM
fd = ref.file
if fd === nothing
fd = open(unlimited ? "/dev/urandom" : "/dev/random")
old, ok = @atomicreplace ref.file nothing => fd
if !ok
close(fd)
fd = old::IOStream
end
end
return fd
end
# Manually implemented to work without the Random machinery
function _rand_uint()
return read(_get_dev_random_fd(true), Cuint)
end
end # os-test
function _ad_hoc_entropy()
println(stderr,
"Entropy pool not available to seed RNG; using ad-hoc entropy sources.")
seed = reinterpret(UInt64, time())
seed = hash(seed, getpid() % UInt)
try
seed = hash(seed, parse(UInt64,
read(pipeline(`ifconfig`, `sha1sum`), String)[1:40],
base = 16) % UInt)
catch
end
return seed
end
function _make_uint_seed()
try
_rand_uint()
catch
return _ad_hoc_entropy() % Cuint
end
end