summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/Crypt/Random/Provider/File.pm
blob: 816f8054d074c03e1329e623c492e42cc0d0067b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package Crypt::Random::Provider::File; 
use strict;
use Carp;
use Math::Pari qw(pari2num);
use Fcntl;

sub _defaultsource { 
    return;
}


sub new { 

    my ($class, %args) = @_;
    my $self = { Source => $args{File} || $args{Device} || $args{Filename} || $class->_defaultsource() };
    return bless $self, $class;

}


sub get_data { 

    my ($self, %params) = @_;
    $self = {} unless ref $self;

    my $size = $params{Size}; 
    my $skip = $params{Skip} || $$self{Skip} || '';
    my $q_skip = quotemeta($skip);

    if ($size && ref $size eq "Math::Pari") { 
        $size = pari2num($size);
    }

    my $bytes = $params{Length} || (int($size / 8) + 1);

    sysopen RANDOM, $$self{Source}, O_RDONLY;

    my($r, $read, $rt) = ('', 0);
    while ($read < $bytes) {
        my $howmany = sysread  RANDOM, $rt, $bytes - $read;
        next unless $howmany;
        if ($howmany == -1) { 
            croak "Error while reading from $$self{Source}. $!"
        }
        $rt =~ s/[$q_skip]//g if $skip;
        $r .= $rt; 
        $read = length $r;
    }

    $r;

}


sub available { 
    my ($class) = @_;
    return -e $class->_defaultsource();
}


1;