File Coverage

blib/lib/Math/BigSimple.pm
Criterion Covered Total %
statement 47 52 90.3
branch 20 26 76.9
condition 8 15 53.3
subroutine 5 5 100.0
pod 4 4 100.0
total 84 102 82.3


line stmt bran cond sub pod time code
1             package Math::BigSimple;
2             require Exporter;
3 3     3   28589 use Math::BigInt;
  3         94152  
  3         20  
4             @ISA = qw(Exporter);
5             @EXPORT = qw(new);
6             @EXPORT_OK = qw(is_simple make_simple);
7             $VERSION = "1.1a";
8             $_DEFAULT_CHECKS = 4;
9             $_DEFAULT_RAND = sub { rand() };
10             sub new
11             {
12 2     2 1 16 my $class = shift;
13 2         5 my($LENGTH, $CHECKS, $RAND);
14 2 100       15 my %param = @_ if(@_ % 2 == 0);
15 2 100       10 if(exists $param{Length}) # Compability mode (with 1.0 version).
16             {
17 1         2 $CHECKS = $param{'Checks'};
18 1         3 $LENGTH = $param{'Length'};
19 1         3 $RAND = $param{'Random'};
20             }
21             else
22             {
23 1         2 ($LENGTH, $CHECKS, $RAND) = @_;
24             }
25 2 50 33     19 if((!$LENGTH) || (int($LENGTH) != $LENGTH))
26             {
27 0         0 die "[error] " . __PACKAGE__ . " $VERSION : number length not specified.";
28             }
29 2 100 66     13 $CHECKS = $Math::BigSimple::_DEFAULT_CHECKS if((!$CHECKS) || (int($CHECKS) != $CHECKS));
30 2 50 33     12 $RAND = $Math::BigSimple::_DEFAULT_RAND if((!$RAND) || (ref($RAND) != 'CODE'));
31              
32 2         9 my $ref = [$LENGTH, $CHECKS, $RAND]; # [$CHECKS, $LENGTH, $RAND] in 1.0.
33 2         6 bless $ref, $class;
34 2         8 return $ref;
35             }
36             sub make
37             {
38 2     2 1 10 my $ref = shift;
39 2         16 my($LENGTH, $CHECKS, $RAND) = @$ref;
40 2         3 while(1)
41             {
42 13         30 my $p = &$RAND();
43 13 50       55 if(int($p * 10) == 0)
44             {
45 0         0 my $repl = 0;
46 0         0 while(!$repl)
47             {
48 0         0 $repl = int(rand() * 10);
49             }
50 0         0 $p += $repl / 10;
51             }
52 13         22 $p = int($p * (10 ** $LENGTH));
53              
54 13 100       28 return $p if(Math::BigSimple::is_simple($p) == 1);
55             }
56             }
57             sub is_simple
58             {
59 64     64 1 242 my($number, $CHECKS) = @_;
60 64 50 33     285 return -1 if((!$number) || (int($number) != $number));
61 64 50       128 $CHECKS = $Math::BigSimple::_DEFAULT_CHECKS if(!$CHECKS);
62              
63 64         215 my $_2 = Math::BigInt->new(2);
64 64         1958 my $coof = $number << 4;
65 64         76 my $simple = 1;
66 64         179 my $_p = Math::BigInt->new($number);
67 64         1918 my $_i1 = Math::BigInt->new($number-1);
68 64         1837 my $_i2 = $_i1->bdiv($_2);
69              
70 64         4025 for(my $count = 0; $count < $CHECKS; $count++)
71             {
72 160         176 $simple = 0;
73 160 100       856 last if($number % 2 == 0);
74 129         244 my $x = Math::BigInt->new(int(&$Math::BigSimple::_DEFAULT_RAND() * $coof) % $number);
75 129 50       3840 next if($x->is_zero());
76              
77 129         1608 my $func = $x->bmodpow($_i1, $_p);
78 129         92792 $func = $func->bstr();
79 129 100 100     2763 last if(($func != 1) && ($func != $number-1));
80              
81 108         416 $simple = 1;
82             }
83 64 100       125 if($simple == 1)
84             {
85 12         93 return 1;
86             }
87             else
88             {
89 52         350 return 0;
90             }
91             }
92             sub make_simple
93             {
94 1     1 1 13 my $g = Math::BigSimple->new(shift);
95 1         5 return $g->make();
96             }
97             __END__