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   71042 use strict;
  2         4  
  2         49  
4 2     2   22 use warnings;
  2         2  
  2         57  
5              
6 2     2   928 use Bytes::Random::Secure::Tiny ();
  2         11493  
  2         322  
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 20026     20026 0 2309178 my ($lower, $upper) = @_;
15              
16 20026   66     32307 $rng ||= Bytes::Random::Secure::Tiny->new();
17              
18 20026         18878 my $is_bigint = ref $upper;
19              
20 20026 100       28302 my $diff = $is_bigint ? $upper->copy()->bsub($lower) : ($upper - $lower);
21              
22 20026 100       331250 my $diff_bin = $is_bigint ? substr( $diff->as_bin(), 2 ) : sprintf('%b', $diff);
23              
24 20026         743446 my $bit_length = length $diff_bin;
25              
26 20026         20577 my $ct_of_chunks_of_32_bits = int( $bit_length / 32 );
27 20026         16135 my $ct_of_leftover_bits = $bit_length % 32;
28              
29 20026 100       31467 my $diff_hex = $is_bigint ? substr( $diff->as_hex(), 2 ) : sprintf('%x', $diff);
30              
31             #my $hex;
32 20026         709605 my $rand;
33              
34 20026         13543 do {
35 28954         4707573 $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 20026 100       10470644 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;