File Coverage

blib/lib/UUID/Generator/PurePerl/Util.pm
Criterion Covered Total %
statement 41 64 64.0
branch 6 8 75.0
condition n/a
subroutine 10 14 71.4
pod 0 5 0.0
total 57 91 62.6


line stmt bran cond sub pod time code
1             package UUID::Generator::PurePerl::Util;
2              
3 11     11   988 use strict;
  11         12  
  11         275  
4 11     11   36 use warnings;
  11         12  
  11         227  
5              
6 11     11   33 use Exporter;
  11         10  
  11         616  
7             *import = \&Exporter::import;
8              
9             our @EXPORT = qw( digest_as_octets digest_as_32bit digest_as_16bit );
10              
11 11     11   41 use Carp;
  11         8  
  11         518  
12 11     11   424 use Digest;
  11         393  
  11         5333  
13              
14             sub fold_into_octets {
15 60     60 0 70 my ($num_octets, $s) = @_;
16              
17 60         79 my $x = "\x0" x $num_octets;
18              
19 60         116 while (length $s > 0) {
20 389         237 my $n = q{};
21 389         487 while (length $x > 0) {
22 1200         1145 my $c = ord(substr $x, -1, 1, q{}) ^ ord(substr $s, -1, 1, q{});
23 1200         978 $n = chr($c) . $n;
24 1200 100       2090 last if length $s <= 0;
25             }
26 389         294 $n = $x . $n;
27              
28 389         509 $x = $n;
29             }
30              
31 60         152 return $x;
32             }
33              
34             {
35             my $digester;
36              
37             sub digester {
38 60 100   60 0 110 if (! defined $digester) {
39 5         6 my $d;
40 5         9 $d = eval { Digest->new('SHA-1') };
  5         35  
41 5 50       15384 $d = eval { Digest->new('MD5') } if $@;
  0         0  
42 5 50       13 $d = UUID::Generator::PurePerl::Util::PseudoDigester->new() if $@;
43 5         8 $digester = $d;
44             }
45              
46 60         53 return $digester;
47             }
48             }
49              
50             sub digest_as_octets {
51 60     60 0 10291 my $num_octets = shift;
52              
53 60         82 my $d = digester();
54 60         126 $d->reset();
55 60         563 $d->add($_) for @_;
56              
57 60         233 return fold_into_octets($num_octets, $d->digest);
58             }
59              
60             sub digest_as_32bit {
61 1     1 0 4 return unpack 'N', digest_as_octets(4, @_);
62             }
63              
64             sub digest_as_16bit {
65 3     3 0 9 return unpack 'n', digest_as_octets(2, @_);
66             }
67              
68             package UUID::Generator::PurePerl::Util::PseudoDigester;
69              
70             sub new {
71 0     0     my $class = shift;
72 0           my $entity = q{};
73              
74 0           return bless \$entity, $class;
75             }
76              
77             sub digest {
78 0     0     my $self = shift;
79              
80 0           my $entity = $$self;
81              
82 0           my $source = q{};
83 0           while (length $entity > 0) {
84             # 4 bytes seems to be enough (8 bytes in ordinal crypt() impl.)
85 0           my $token = substr($entity, 0, 4, q{}) . "\0\0\0\0";
86 0           $source .= crypt $token, $token;
87             }
88              
89 0           my @r = ( 0, 0, 0, 0 ); # 32bits * 4
90 0           my $index = 0;
91 0           while (length $source > 0) {
92 0           my $token = substr($source, 0, 4, q{}) . "\0\0\0\0";
93 0           $r[$index] ^= unpack 'N', $token;
94              
95 0           $index = ($index + 1) % 4;
96             }
97              
98 0           return pack 'NNNN', @r;
99             }
100              
101             sub reset {
102 0     0     my $self = shift;
103 0           $$self = q{};
104 0           return $self;
105             }
106              
107             sub add {
108 0     0     my ($self, $data) = @_;
109 0           $$self .= $data;
110 0           return $self;
111             }
112              
113             1;
114             __END__