line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Math::Random::Secure; |
2
|
|
|
|
|
|
|
$Math::Random::Secure::VERSION = '0.08'; |
3
|
|
|
|
|
|
|
# ABSTRACT: Cryptographically-secure, cross-platform replacement for rand() |
4
|
|
|
|
|
|
|
|
5
|
5
|
|
|
5
|
|
174841
|
use strict; |
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
109
|
|
6
|
5
|
|
|
5
|
|
83
|
use 5.008; |
|
5
|
|
|
|
|
10
|
|
7
|
5
|
|
|
5
|
|
16
|
use base qw(Exporter); |
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
378
|
|
8
|
5
|
|
|
5
|
|
1450
|
use Math::Random::Secure::RNG; |
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
161
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# ISAAC, a 32-bit generator, should only be capable of generating numbers |
11
|
|
|
|
|
|
|
# between 0 and 2^32 - 1. We want _to_float to generate numbers possibly |
12
|
|
|
|
|
|
|
# including 0, but always less than 1.0. Dividing the integer produced |
13
|
|
|
|
|
|
|
# by irand() by this number should do that exactly. |
14
|
5
|
|
|
5
|
|
33
|
use constant DIVIDE_BY => 2**32; |
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
1343
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $RNG; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our @EXPORT_OK = qw(rand srand irand); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub rand (;$) { |
21
|
40000
|
|
|
40000
|
1
|
74122
|
my ($limit) = @_; |
22
|
40000
|
|
|
|
|
33959
|
my $int = irand(); |
23
|
40000
|
|
|
|
|
37968
|
return _to_float($int, $limit); |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub irand (;$) { |
27
|
80605
|
|
|
80605
|
1
|
115580
|
my ($limit) = @_; |
28
|
80605
|
100
|
|
|
|
92586
|
Math::Random::Secure::srand() if !defined $RNG; |
29
|
80605
|
|
|
|
|
1144608
|
my $int = $RNG->irand(); |
30
|
80605
|
100
|
|
|
|
2293491
|
if (defined $limit) { |
31
|
|
|
|
|
|
|
# We can't just use the mod operator because it will bias |
32
|
|
|
|
|
|
|
# our output. Search for "modulo bias" on the Internet for |
33
|
|
|
|
|
|
|
# details. This is slower than mod(), but does not have a bias, |
34
|
|
|
|
|
|
|
# as demonstrated by our uniform.t test. |
35
|
30000
|
|
|
|
|
30309
|
return int(_to_float($int, $limit)); |
36
|
|
|
|
|
|
|
} |
37
|
50605
|
|
|
|
|
45135
|
return $int; |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub srand (;$) { |
41
|
17
|
|
|
17
|
1
|
18625
|
my ($value) = @_; |
42
|
17
|
100
|
|
|
|
72
|
if (defined $RNG) { |
43
|
14
|
100
|
|
|
|
46
|
if (defined $value) { |
44
|
12
|
|
|
|
|
388
|
$RNG->seed($value); |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
else { |
47
|
2
|
|
|
|
|
82
|
$RNG->clear_seed; |
48
|
|
|
|
|
|
|
} |
49
|
14
|
|
|
|
|
442
|
$RNG->clear_rng; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
else { |
52
|
3
|
|
|
|
|
5
|
my %args; |
53
|
3
|
50
|
|
|
|
13
|
if (defined $value) { |
54
|
0
|
|
|
|
|
0
|
$args{seed} = $value; |
55
|
|
|
|
|
|
|
} |
56
|
3
|
|
|
|
|
47
|
$RNG = Math::Random::Secure::RNG->new(%args); |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
# This makes srand return the seed and also makes sure that we |
59
|
|
|
|
|
|
|
# get the seed right now, if no $value was passed. |
60
|
17
|
|
|
|
|
1407
|
return $RNG->seed; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub _to_float { |
64
|
70000
|
|
|
70000
|
|
50162
|
my ($integer, $limit) = @_; |
65
|
70000
|
100
|
|
|
|
79175
|
$limit = 1 if !$limit; |
66
|
70000
|
|
|
|
|
136358
|
return ($integer / DIVIDE_BY) * $limit; |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
__PACKAGE__ |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
__END__ |