File Coverage

blib/lib/Math/Random/Secure.pm
Criterion Covered Total %
statement 37 38 97.3
branch 11 12 91.6
condition n/a
subroutine 10 10 100.0
pod 3 3 100.0
total 61 63 96.8


line stmt bran cond sub pod time code
1             package Math::Random::Secure;
2             BEGIN {
3 5     5   111871 $Math::Random::Secure::VERSION = '0.06';
4             }
5 5     5   26 use strict;
  5         6  
  5         70  
6 5     5   67 use 5.008;
  5         11  
7 5     5   14 use base qw(Exporter);
  5         6  
  5         346  
8 5     5   1369 use Math::Random::Secure::RNG;
  5         9  
  5         150  
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   20 use constant DIVIDE_BY => 2**32;
  5         6  
  5         1295  
15              
16             our $RNG;
17              
18             our @EXPORT_OK = qw(rand srand irand);
19              
20             sub rand (;$) {
21 40000     40000 1 84601 my ($limit) = @_;
22 40000         38259 my $int = irand();
23 40000         43532 return _to_float($int, $limit);
24             }
25              
26             sub irand (;$) {
27 80605     80605 1 118006 my ($limit) = @_;
28 80605 100       95584 Math::Random::Secure::srand() if !defined $RNG;
29 80605         1221926 my $int = $RNG->irand();
30 80605 100       2409336 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         29448 return int(_to_float($int, $limit));
36             }
37 50605         49967 return $int;
38             }
39              
40             sub srand (;$) {
41 17     17 1 8060 my ($value) = @_;
42 17 100       36 if (defined $RNG) {
43 14 100       22 if (defined $value) {
44 12         212 $RNG->seed($value);
45             }
46             else {
47 2         46 $RNG->clear_seed;
48             }
49 14         216 $RNG->clear_rng;
50             }
51             else {
52 3         3 my %args;
53 3 50       9 if (defined $value) {
54 0         0 $args{seed} = $value;
55             }
56 3         37 $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         807 return $RNG->seed;
61             }
62              
63             sub _to_float {
64 70000     70000   51750 my ($integer, $limit) = @_;
65 70000 100       82915 $limit = 1 if !$limit;
66 70000         138434 return ($integer / DIVIDE_BY) * $limit;
67             }
68              
69             __PACKAGE__
70              
71             __END__