Skip to content

Commit 0c364db

Browse files
author
Ruben
committed
first release
1 parent e02944c commit 0c364db

15 files changed

+380
-1
lines changed

Build.PL

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use 5.006;
2+
use strict;
3+
use warnings;
4+
use Module::Build;
5+
6+
my $builder = Module::Build->new(
7+
module_name => 'UUID::Random::Secure',
8+
license => 'artistic_2',
9+
dist_author => q{Ruben Navarro <[email protected]>},
10+
dist_version_from => 'lib/UUID/Random/Secure.pm',
11+
release_status => 'stable',
12+
configure_requires => {
13+
'Module::Build' => 0,
14+
},
15+
build_requires => {
16+
'Test::More' => 0,
17+
'Module::Build' => 0,
18+
},
19+
requires => {
20+
'Exporter' => 0,
21+
},
22+
add_to_cleanup => [ 'UUID-Random-Secure-*' ],
23+
create_makefile_pl => 'traditional',
24+
);
25+
26+
$builder->create_build_script();

Changes

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Revision history for UUID-Random-Secure
2+
3+
0.01 2016-08-20
4+
First release.
5+

MANIFEST

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Build.PL
2+
Changes
3+
lib/UUID/Random/Secure.pm
4+
MANIFEST This list of files
5+
README
6+
t/00-load.t
7+
t/manifest.t
8+
t/pod-coverage.t
9+
t/pod.t

README

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
NAME
2+
UUID::Random::Secure - Cryptographically-secure random UUID generator
3+
4+
VERSION
5+
version 0.01
6+
7+
SYNOPSIS
8+
use UUID::Random::Secure qw(generate_uuid);
9+
use feature qw(say);
10+
11+
say generate_uuid();
12+
say UUID::Random::Secure->generate();
13+
say UUID::Random::Secure->new->generate();
14+
15+
DESCRIPTION
16+
UUID::Random::Secure generates cryptographically-secure UUID strings.
17+
It tries to use one of the following pseudo-random number generators:
18+
19+
* Crypt::PRNG
20+
21+
* Crypt::OpenSSL::Random
22+
23+
* Bytes::Random::Secure
24+
25+
* Net::SSLeay
26+
27+
* Crypt::Random
28+
29+
* Math::Random::Secure
30+
31+
If none of these modules can be loaded or are already loaded
32+
Perl’s rand will be used as an unsecure fallback.
33+
34+
INSTALLATION
35+
36+
To install this module, run the following commands:
37+
38+
perl Build.PL
39+
./Build
40+
./Build test
41+
./Build install
42+
43+
AUTHOR
44+
Ruben Navarro <[email protected]>
45+
46+
COPYRIGHT AND LICENSE
47+
48+
49+
Copyright 2016 Ruben Navarro.
50+
51+
This program is free software; you can redistribute it and/or modify it
52+
under the terms of the the Artistic License (2.0).
53+

README.md

-1
This file was deleted.

ignore.txt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Makefile
2+
Makefile.old
3+
Build
4+
Build.bat
5+
META.*
6+
MYMETA.*
7+
.build/
8+
_build/
9+
cover_db/
10+
blib/
11+
inc/
12+
.lwpcookies
13+
.last_cover_stats
14+
nytprof.out
15+
pod2htm*.tmp
16+
pm_to_blib
17+
UUID-Random-Secure-*
18+
UUID-Random-Secure-*.tar.gz

lib/.DS_Store

6 KB
Binary file not shown.

lib/UUID/.DS_Store

6 KB
Binary file not shown.

lib/UUID/Random/.DS_Store

6 KB
Binary file not shown.

lib/UUID/Random/Secure.pm

+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package UUID::Random::Secure;
2+
use strict;
3+
use warnings;
4+
5+
our $VERSION = '0.01';
6+
7+
use base 'Exporter';
8+
our @EXPORT = qw/generate_uuid/;
9+
my $BYTELEN = 128 / 8;
10+
11+
our $PRNG;
12+
13+
our @models = (
14+
[ 'Crypt::PRNG' => '_random_bytes_hex_CP' ],
15+
[ 'Crypt::OpenSSL::Random' => '_random_bytes_hex_COR' ],
16+
[ 'Bytes::Random::Secure' => '_random_bytes_hex_BRS' ],
17+
[ 'Net::SSLeay' => '_random_bytes_hex_NS' ],
18+
[ 'Crypt::Random' => '_random_bytes_hex_CR' ],
19+
[ 'Math::Random::Secure' => '_random_bytes_hex_MRS' ],
20+
);
21+
22+
sub new{ bless {},shift };
23+
24+
sub generate {
25+
my $hex = _random_bytes_hex();
26+
return join('-',unpack("A8A4A4A4A12",$hex));
27+
}
28+
29+
*generate_uuid = \&generate;
30+
31+
sub _random_bytes_hex{
32+
my $length = shift;
33+
34+
my $impl_name = @{ _detect_prng() }[1];
35+
my $impl = \&{$impl_name};
36+
my $out = $impl->($BYTELEN) || _random_bytes_hex_fallback($BYTELEN)
37+
}
38+
39+
sub _random_bytes_hex_CP {
40+
my $length = shift;
41+
return Crypt::PRNG::random_bytes_hex($length);
42+
}
43+
44+
sub _random_bytes_hex_COR {
45+
my $length = shift;
46+
my $bytes;
47+
if (Crypt::OpenSSL::Random::random_status()) {
48+
$bytes = Crypt::OpenSSL::Random::random_bytes($length);
49+
return unpack( 'H*', $bytes );
50+
}
51+
return
52+
}
53+
54+
sub _random_bytes_hex_BRS {
55+
my $length = shift;
56+
Bytes::Random::Secure::random_bytes_hex($length)
57+
}
58+
59+
sub _random_bytes_hex_NS {
60+
my $length = shift;
61+
my $bytes;
62+
if (Net::SSLeay::RAND_status() == 1) {
63+
if (Net::SSLeay::RAND_bytes($bytes, $length) == 1) {
64+
return unpack( 'H*', $bytes );
65+
}
66+
}
67+
return
68+
}
69+
70+
sub _random_bytes_hex_CR {
71+
my $length = shift;
72+
my $bytes = Crypt::Random::makerandom_octet(Length=>$length);
73+
return unpack( 'H*', $bytes );
74+
}
75+
76+
sub _random_bytes_hex_fallback {
77+
my $length = shift;
78+
my @chars = ('a'..'f',0..9);
79+
join '', map $chars[ irand(scalar @chars) ], 1 .. $length * 2
80+
}
81+
82+
sub _random_bytes_hex_MRS {
83+
no warnings 'redefine';
84+
*irand = \&Math::Random::Secure::rand;
85+
return
86+
}
87+
88+
sub _is_module_loaded {
89+
my $module = shift;
90+
foreach my $i(keys %INC){
91+
$i =~ s{/}{::}g;
92+
$i =~ s{.pm}{};
93+
return 1 if($i eq $module);
94+
}
95+
return
96+
}
97+
98+
sub _detect_prng {
99+
return $PRNG if $PRNG;
100+
101+
foreach my $m(@models) {
102+
if (_is_module_loaded($m->[0]) ) {
103+
return $PRNG = $m;
104+
}
105+
}
106+
107+
foreach my $m(@models){
108+
if(eval "require @{[ $m->[0] ]}"){
109+
return $PRNG = $m;
110+
}
111+
}
112+
113+
return;
114+
}
115+
116+
sub irand(;$) {
117+
rand(shift);
118+
}
119+
120+
1;
121+
122+
__END__
123+
=head1 NAME
124+
125+
UUID::Random::Secure - Cryptographically-secure random UUID generator
126+
127+
=head1 VERSION
128+
129+
Version 0.01
130+
131+
=head1 SYNOPSIS
132+
133+
use UUID::Random::Secure qw(generate_uuid);
134+
use feature qw(say);
135+
136+
say generate_uuid();
137+
say UUID::Random::Secure->generate();
138+
say UUID::Random::Secure->new->generate();
139+
140+
141+
=head1 DESCRIPTION
142+
143+
UUID::Random::Secure generates cryptographically-secure UUID strings.
144+
It tries to use one of the following pseudo-random number generators:
145+
146+
=over
147+
148+
=item * L<Crypt::PRNG>
149+
150+
=item * L<Crypt::OpenSSL::Random>
151+
152+
=item * L<Bytes::Random::Secure>
153+
154+
=item * L<Net::SSLeay>
155+
156+
=item * L<Crypt::Random>
157+
158+
=item * L<Math::Random::Secure>
159+
160+
161+
=back
162+
163+
If none of these modules can be loaded or are already loaded
164+
Perl's rand will be used as an unsecure fallback.
165+
166+
167+
=head1 AUTHOR
168+
169+
Ruben Navarro, C<< <[email protected]> >>
170+
171+
=head1 SUPPORT
172+
173+
Please report any bugs or feature requests through the issue tracker
174+
at L<https://github.com/rbnx/UUID-Random-Secure/issues>.
175+
176+
177+
=head1 LICENSE AND COPYRIGHT
178+
179+
Copyright 2016 Ruben Navarro.
180+
181+
This program is free software; you can redistribute it and/or modify it
182+
under the terms of the the Artistic License (2.0).
183+
184+
=cut

t/.DS_Store

6 KB
Binary file not shown.

t/00-load.t

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!perl -T
2+
use 5.006;
3+
use strict;
4+
use warnings;
5+
use Test::More;
6+
7+
plan tests => 1;
8+
9+
BEGIN {
10+
use_ok( 'UUID::Random::Secure' ) || print "Bail out!\n";
11+
}
12+
13+
diag( "Testing UUID::Random::Secure $UUID::Random::Secure::VERSION, Perl $], $^X" );

t/manifest.t

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!perl -T
2+
use 5.006;
3+
use strict;
4+
use warnings;
5+
use Test::More;
6+
7+
unless ( $ENV{RELEASE_TESTING} ) {
8+
plan( skip_all => "Author tests not required for installation" );
9+
}
10+
11+
my $min_tcm = 0.9;
12+
eval "use Test::CheckManifest $min_tcm";
13+
plan skip_all => "Test::CheckManifest $min_tcm required" if $@;
14+
15+
ok_manifest();

xt/.DS_Store

6 KB
Binary file not shown.

xt/boilerplate.t

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!perl -T
2+
use 5.006;
3+
use strict;
4+
use warnings;
5+
use Test::More;
6+
7+
plan tests => 3;
8+
9+
sub not_in_file_ok {
10+
my ($filename, %regex) = @_;
11+
open( my $fh, '<', $filename )
12+
or die "couldn't open $filename for reading: $!";
13+
14+
my %violated;
15+
16+
while (my $line = <$fh>) {
17+
while (my ($desc, $regex) = each %regex) {
18+
if ($line =~ $regex) {
19+
push @{$violated{$desc}||=[]}, $.;
20+
}
21+
}
22+
}
23+
24+
if (%violated) {
25+
fail("$filename contains boilerplate text");
26+
diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
27+
} else {
28+
pass("$filename contains no boilerplate text");
29+
}
30+
}
31+
32+
sub module_boilerplate_ok {
33+
my ($module) = @_;
34+
not_in_file_ok($module =>
35+
'the great new $MODULENAME' => qr/ - The great new /,
36+
'boilerplate description' => qr/Quick summary of what the module/,
37+
'stub function definition' => qr/function[12]/,
38+
);
39+
}
40+
41+
TODO: {
42+
local $TODO = "Need to replace the boilerplate text";
43+
44+
not_in_file_ok(README =>
45+
"The README is used..." => qr/The README is used/,
46+
"'version information here'" => qr/to provide version information/,
47+
);
48+
49+
not_in_file_ok(Changes =>
50+
"placeholder date/time" => qr(Date/time)
51+
);
52+
53+
module_boilerplate_ok('lib/UUID/Random/Secure.pm');
54+
55+
56+
}
57+

0 commit comments

Comments
 (0)