Crypt-HSXKPasswd

 view release on metacpan or  search on metacpan

lib/Crypt/HSXKPasswd/RNG/RandomDotOrg.pm  view on Meta::CPAN

}

#
# --- Public Instance functions -----------------------------------------------
#

#####-SUB-#####################################################################
# Type       : INSTANCE
# Purpose    : Override the parent random_numbers() function and generate
#              random numbers between 0 and 1.
# Returns    : An array of numbers between 0 and 1
# Arguments  : 1) the number of random numbers needed to produce 1 password.
# Throws     : Croaks on error, carps if it receives invalid numbers from RDO
# Notes      : 
# See Also   :
sub random_numbers{
    my @args = @_;
    my $self = shift @args;
    _force_instance($self);
    
    # validate args
    state $args_check = compile(PositiveInteger);
    my ($num_per_password) = $args_check->(@args);
    
    # figure out how many numbers to request from the web service
    my $num = 0;
    if($self->{num_absolute}){
        $num = $self->{num_absolute};
    }else{
        $num = $num_per_password * $self->{num_passwords};
    }
    unless($num){
        _error('failed to determine how many passwords to request from the web service (this error should be impossible!)');
    }
    
    # generate the URL + query string
    my %query_params = (
        num => $num,
        min => 0,
        max => $RDO_MAX_INT,
        col => 1,
        base => 10,
        format => 'plain',
        rnd => 'new',
    );
    my $url = URI->new($RDO_URL);
    $url->query_form(%query_params);
    
    # assemble/prepare the web request
    my $ua = LWP::UserAgent->new();
    $ua->timeout($self->{timeout});
    $ua->agent($_CLASS.' (on behalf of '.$self->{email}.') ');
    
    # execute the web request
    my $response = $ua->get($url);
    if($response->is_error()){
        _error('failed to retrieve numbers from Random.Org web service with error code '.$response->code().' ('.$response->message.')');
    }
    
    # parse the result
    my $raw_numbers = $response->decoded_content();
    my @ans = ();
    RESPONSE_LINE:
    foreach my $line (split /\n/sx, $raw_numbers){
        # validate the line
        unless($line && $line =~ m/^\d+$/sx){
            _warn("received invalid number from Random.Org ($line)");
            next RESPONSE_LINE;
        }
        
        # convert from integer to decimal between 0 and 1
        my $dec = $line/$RDO_MAX_INT;
        unless($dec >= 0 && $dec <=1){
            _warn("failed to convert integer from from Random.Org to decimal between 0 and 1 ($line => $dec)");
            next RESPONSE_LINE;
        }
        
        # store the decimal
        push @ans, $dec;
    }
    unless(scalar @ans){
        _error('no valid random numbers found in response from Random.Org web service');
    }
    
    # return the random numbers
    return @ans;
}

1; # because Perl is just a little bit odd :)



( run in 1.377 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )