File Coverage

blib/lib/Crypt/HSXKPasswd/RNG/DevUrandom.pm
Criterion Covered Total %
statement 41 70 58.5
branch 0 4 0.0
condition n/a
subroutine 14 17 82.3
pod 0 2 0.0
total 55 93 59.1


line stmt bran cond sub pod time code
1             package Crypt::HSXKPasswd::RNG::DevUrandom;
2              
3 3     3   19 use parent Crypt::HSXKPasswd::RNG;
  3         5  
  3         24  
4              
5             # import required modules
6 3     3   237 use strict;
  3         6  
  3         99  
7 3     3   19 use warnings;
  3         5  
  3         114  
8 3     3   29 use Carp; # for nicer 'exception' handling for users of the module
  3         162  
  3         268  
9 3     3   18 use Fatal qw( :void open close binmode sysread ); # make builtins throw exceptions on failure
  3         6  
  3         27  
10 3     3   7209 use English qw( -no_match_vars ); # for more readable code
  3         8  
  3         25  
11 3     3   1627 use Readonly; # for truly constant constants
  3         6  
  3         210  
12 3     3   18 use Type::Params qw( compile ); # for parameter validation with Type::Tiny objects
  3         5  
  3         44  
13 3     3   887 use Crypt::HSXKPasswd::Types qw( :types ); # for custom type checking
  3         6  
  3         40  
14 3     3   8086 use Crypt::HSXKPasswd::Helper; # exports utility functions like _error & _warn
  3         7  
  3         305  
15              
16             # set things up for using UTF-8
17 3     3   78 use 5.016; # min Perl for good UTF-8 support, implies feature 'unicode_strings'
  3         19  
18 3     3   17 use Encode qw(encode decode);
  3         6  
  3         207  
19 3     3   19 use utf8;
  3         5  
  3         27  
20             binmode STDOUT, ':encoding(UTF-8)';
21              
22             # Copyright (c) 2015, Bart Busschots T/A Bartificer Web Solutions All rights
23             # reserved.
24             #
25             # Code released under the FreeBSD license (included in the POD at the bottom of
26             # HSXKPasswd.pm)
27              
28             #
29             # --- Constants ---------------------------------------------------------------
30             #
31              
32             # version info
33 3     3   165 use version; our $VERSION = qv('1.2');
  3         6  
  3         18  
34              
35             # utility variables
36             Readonly my $_CLASS => __PACKAGE__;
37              
38             #
39             # --- Constructor -------------------------------------------------------------
40             #
41              
42             #####-SUB-#####################################################################
43             # Type : CONSTRUCTOR (CLASS)
44             # Returns : An object of type Crypt::HSXKPasswd::RNG::DevUrandom
45             # Arguments : NONE
46             # Throws : Croaks on invalid invocation and invalid args, or if
47             # /dev/urandom does not exist
48             # Notes :
49             # See Also :
50             sub new{
51 0     0 0   my $class = shift;
52 0           _force_class($class);
53            
54             # make sure /dev/urandom exists
55 0 0         unless(-e '/dev/urandom'){
56 0           _error('/dev/urandom does not exist on this computer');
57             }
58            
59             # bless and return an empty object
60 0           my $instance = {};
61 0           bless $instance, $class;
62 0           return $instance;
63             }
64              
65             #
66             # --- Public Instance functions -----------------------------------------------
67             #
68              
69             #####-SUB-#####################################################################
70             # Type : INSTANCE
71             # Purpose : Override the parent random_numbers() function and generate
72             # random numbers between 0 and 1.
73             # Returns : An array of numbers between 0 and 1
74             # Arguments : 1) the number of random numbers needed to produce 1 password.
75             # Throws : NOTHING
76             # Notes : This function will return the number of random numbers needed
77             # for a single password.
78             # See Also :
79             sub random_numbers{
80 0     0 0   my @args = @_;
81 0           my $self = shift @args;
82 0           _force_instance($self);
83            
84             # validate args
85 0           state $args_check = compile(PositiveInteger);
86 0           my ($num) = $args_check->(@args);
87            
88             # generate the random numbers
89 0           my @ans = ();
90 0           my $num_to_generate = $num;
91 0           while($num_to_generate > 0){
92 0           push @ans, $_CLASS->_rand();
93 0           $num_to_generate--;
94             }
95            
96             # return the random numbers
97 0           return @ans;
98             }
99              
100             #
101             # --- Private Helper functions -------------------------------------------------
102             #
103              
104             #####-SUB-######################################################################
105             # Type : CLASS (PRIVATE)
106             # Purpose : Generate a random number from /dev/urandom
107             # Returns : A random number beween 0 and 1
108             # Arguments : NONE
109             # Throws : Croaks on invalid invocation or IO error
110             # Notes :
111             # See Also :
112             sub _rand{
113 0     0     my $class = shift;
114            
115             # validate the args
116 0           _force_class($class);
117            
118             # try geneate the random number
119 0           my $rand;
120             eval{
121 0           open my $DEV_URANDOM_FH, '<:raw', '/dev/urandom';
122 0           sysread $DEV_URANDOM_FH, my $rand_wip, 4;
123 0           my $rand_long = unpack 'L', $rand_wip;
124 0           close $DEV_URANDOM_FH;
125 0           $rand = $rand_long/4_294_967_296;
126 0 0         }or do{
127 0           _error("failed to generate random number with error: $EVAL_ERROR");
128             };
129            
130             # return the random number
131 0           return $rand;
132             }
133              
134             1; # because Perl is just a little bit odd :)