From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

##
## Copyright (c) 1998-2025, Vipul Ved Prakash. All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.
## The WIN32API implementation below is based on code written by
## Leon Timmermans (Leont) as implemented here by Timothy Legge (timlegge)
use strict;
use Math::Pari qw(pari2num);
use Crypt::URandom qw/urandom/;
our $VERSION = '1.57';
sub new {
my ($class, %params) = @_;
my $self = { Source => $params{Source} };
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);
my $source;
if (eval { require Win32::API }) {
my $genrand = Win32::API->new('advapi32', 'INT SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength)')
or Carp::croak("Could not import SystemFunction036: $^E");
$source = sub {
my ($count) = @_;
return '' if $count == 0;
Carp::croak('The Length argument must be supplied and must be an integer') if not defined $bytes or $bytes =~ /\D/;
my $buffer = chr(0) x $count;
$genrand->Call($buffer, $count) or Carp::croak("Could not read random data");
return $buffer;
};
}
else {
Carp::croak('Win32::API is required');
}
my($r, $read, $rt) = ('', 0);
while ($read < $bytes) {
$rt = &$source($bytes - $read);
$rt =~ s/[$q_skip]//g if $skip;
$r .= $rt;
$read = length $r;
}
$r;
}
sub available {
if (eval { require Win32::API }) {
return 1;
} else {
return 0;
};
}
1;