File Coverage

lib/Math/ProvablePrime/Rand.pm
Criterion Covered Total %
statement 22 23 95.6
branch 8 8 100.0
condition 2 3 66.6
subroutine 4 5 80.0
pod 0 1 0.0
total 36 40 90.0


line stmt bran cond sub pod time code
1             package Math::ProvablePrime::Rand;
2              
3 2     2   113636 use strict;
  2         4  
  2         52  
4 2     2   9 use warnings;
  2         3  
  2         47  
5              
6 2     2   854 use Bytes::Random::Secure::Tiny ();
  2         13154  
  2         348  
7              
8             my $rng;
9              
10             #Return a random integer N such that $lower <= N <= $upper.
11             #cf. Python random.randint()
12             #TODO: test this
13             sub int {
14 10806     10806 0 2061543 my ($lower, $upper) = @_;
15              
16 10806   66     21455 $rng ||= Bytes::Random::Secure::Tiny->new();
17              
18 10806         19536 my $is_bigint = ref $upper;
19              
20 10806 100       19000 my $diff = $is_bigint ? $upper->copy()->bsub($lower) : ($upper - $lower);
21              
22 10806 100       269915 my $diff_bin = $is_bigint ? substr( $diff->as_bin(), 2 ) : sprintf('%b', $diff);
23              
24 10806         739514 my $bit_length = length $diff_bin;
25              
26 10806         16427 my $ct_of_chunks_of_32_bits = int( $bit_length / 32 );
27 10806         13688 my $ct_of_leftover_bits = $bit_length % 32;
28              
29 10806 100       21992 my $diff_hex = $is_bigint ? substr( $diff->as_hex(), 2 ) : sprintf('%x', $diff);
30              
31             #my $hex;
32 10806         719622 my $rand;
33              
34 10806         13036 do {
35 15675         4691839 $rand = Math::BigInt->from_bin( $rng->string_from('01', length $diff_bin) );
36              
37             #$hex = join( q<>, map { sprintf '%08x', _irand() } 1 .. $ct_of_chunks_of_32_bits );
38              
39             #Now the remaining bits
40             #if ($ct_of_leftover_bits) {
41             # substr( $hex, 0, 0) = sprintf '%x', int rand( (2 ** $ct_of_leftover_bits) );
42             #}
43             #$rand->badd($lower);
44              
45             #} while (length($hex) == length($diff_hex)) && ($hex gt $diff_hex);
46             } while $rand->bgt($diff);
47              
48             #TODO: Allow this to return scalars.
49             #return $is_bigint ? Math::BigInt->from_hex($hex)->badd($lower) : ($lower + hex $hex);
50 10806 100       10466020 return $is_bigint ? $rand->badd($lower) : ($rand->numify() + $lower);
51             }
52              
53             #cf. Bytes::Random::Secure::Tiny … but NOT cryptographic-strength
54             sub _irand {
55 0     0     return CORE::int(0.5 + rand) + CORE::int(rand 0xffffffff);
56             }
57              
58             1;