File Coverage

blib/lib/Data/SimplePassword.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             #
2              
3             package Data::SimplePassword;
4              
5 10     10   107014 use Moo;
  10         285861  
  10         65  
6 10     10   63035 use MooX::ClassAttribute;
  0            
  0            
7              
8             use Carp;
9             use UNIVERSAL::require;
10             use Crypt::Random ();
11              
12             # ABSTRACT: Simple random password generator
13              
14             our $VERSION = '0.10';
15              
16             class_has 'class' => (
17             is => 'rw',
18             default => sub {
19             Math::Random::MT->use
20             ? "Math::Random::MT"
21             : Math::Random::MT::Perl->use
22             ? "Math::Random::MT::Perl"
23             : "Data::SimplePassword::exception";
24             },
25             );
26              
27             has 'seed_num' => (
28             is => 'rw',
29             default => 1, # now internal use only, up to 624
30             );
31              
32             has 'provider' => (
33             is => 'rw',
34             trigger => sub {
35             my $self = shift;
36             my ($provider) = @_;
37              
38             $self->is_available_provider( $provider )
39             or croak "RNG provider '$_[0]' is not available on this machine.";
40             },
41             );
42              
43             has '_default_chars' => (
44             is => 'ro',
45             default => sub { [ 0..9, 'a'..'z', 'A'..'Z' ] },
46             );
47              
48             sub chars {
49             my $self = shift;
50              
51             if( scalar @_ > 0 ){
52             croak "each chars must be a letter or an integer."
53             if scalar grep { length( $_ ) != 1 } @_;
54              
55             $self->{_chars} = [ @_ ];
56             }
57              
58             return wantarray ? @{ $self->{_chars} } : $self->{_chars};
59             }
60              
61             sub is_available_provider {
62             my $self = shift;
63             my ($provider) = @_;
64              
65             if( defined $provider and $provider ne '' ){
66             my $pkg = sprintf "Crypt::Random::Provider::%s", $provider;
67             return eval "use $pkg; $pkg->available()";
68             }
69              
70             return;
71             }
72              
73             sub make_password {
74             my $self = shift;
75             my $len = shift || 8;
76              
77             croak "length must be an integer."
78             unless $len =~ /^\d+$/o;
79              
80             my @chars = defined $self->chars && ref $self->chars eq 'ARRAY'
81             ? @{ $self->chars }
82             : @{ $self->_default_chars };
83              
84             my $gen = $self->class->new(
85             map { Crypt::Random::makerandom( Size => 32, Strength => 1, Provider => $self->provider ) } 1 .. $self->seed_num
86             );
87              
88             my $password;
89             while( $len-- ){
90             $password .= $chars[ $gen->rand( scalar @chars ) ];
91             }
92              
93             return $password;
94             }
95              
96             { package # hide from PAUSE
97             Data::SimplePassword::exception;
98              
99             use strict;
100             use Carp;
101              
102             AUTOLOAD { croak "couldn't find any suitable MT classes." }
103             }
104              
105             1;
106              
107             __END__