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   143652 use strict;
  2         5  
  2         86  
4 2     2   12 use warnings;
  2         5  
  2         72  
5              
6 2     2   1218 use Bytes::Random::Secure::Tiny ();
  2         17795  
  2         510  
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 9197     9197 0 2045801 my ($lower, $upper) = @_;
15              
16 9197   66     22569 $rng ||= Bytes::Random::Secure::Tiny->new();
17              
18 9197         21200 my $is_bigint = ref $upper;
19              
20 9197 100       22577 my $diff = $is_bigint ? $upper->copy()->bsub($lower) : ($upper - $lower);
21              
22 9197 100       271256 my $diff_bin = $is_bigint ? substr( $diff->as_bin(), 2 ) : sprintf('%b', $diff);
23              
24 9197         726915 my $bit_length = length $diff_bin;
25              
26 9197         18763 my $ct_of_chunks_of_32_bits = int( $bit_length / 32 );
27 9197         15311 my $ct_of_leftover_bits = $bit_length % 32;
28              
29 9197 100       24504 my $diff_hex = $is_bigint ? substr( $diff->as_hex(), 2 ) : sprintf('%x', $diff);
30              
31             #my $hex;
32 9197         706194 my $rand;
33              
34 9197         13835 do {
35 13252         4822498 $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 9197 100       10710582 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;