File Coverage

blib/lib/Crypt/Digest.pm
Criterion Covered Total %
statement 38 39 97.4
branch 8 10 80.0
condition 5 6 83.3
subroutine 9 10 90.0
pod 5 5 100.0
total 65 70 92.8


line stmt bran cond sub pod time code
1             package Crypt::Digest;
2              
3 61     61   4057949 use strict;
  61         125  
  61         2343  
4 61     61   463 use warnings;
  61         121  
  61         9694  
5             our $VERSION = '0.089_001';
6              
7             require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import';
8             our %EXPORT_TAGS = ( all => [qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u )] );
9             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
10             our @EXPORT = qw();
11              
12 61     61   456 use Carp;
  61         172  
  61         5106  
13             $Carp::Internal{(__PACKAGE__)}++;
14 61     61   19552 use CryptX;
  61         143  
  61         33338  
15              
16             ### the following methods/functions are implemented in XS:
17             # - new
18             # - hashsize
19             # - clone
20             # - reset
21             # - digest
22             # - hexdigest
23             # - b64digest
24             # - add
25             # - digest_data
26             # - digest_data_hex
27             # - digest_data_b64
28             # - digest_data_b64u
29             # - DESTROY
30              
31             ### METHODS
32              
33             sub addfile {
34 1229     1229 1 179769 my ($self, $file) = @_;
35              
36 1229         2002 my ($handle, $close_handle);
37 1229 100 100     7938 if (ref($file) && eval { defined fileno($file) }) {
  139 100 66     746  
38 138         292 $handle = $file;
39             }
40             elsif (defined($file) && !ref($file)) {
41 1090 50       57960 open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!";
42 1090         3722 binmode($handle);
43 1090         2775 $close_handle = 1;
44             }
45             else {
46 1         234 croak "FATAL: invalid handle";
47             }
48              
49 1228         1897 my $n;
50 1228         2377 my $buf = "";
51             {
52 1228         1955 local $SIG{__DIE__} = \&CryptX::_croak;
  1228         7382  
53 1228         37064 while (($n = read($handle, $buf, 32*1024))) {
54 1228         51053 $self->add($buf)
55             }
56 1228 50       5956 croak "FATAL: read failed: $!" unless defined $n;
57             }
58 1228 100       14975 close($handle) if $close_handle;
59              
60 1228         21961 return $self;
61             }
62              
63 0     0   0 sub CLONE_SKIP { 1 } # prevent cloning
64              
65             ### FUNCTIONS
66              
67 272     272 1 1784 sub digest_file { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->digest }
  272         3058  
68 274     274 1 1772 sub digest_file_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->hexdigest }
  274         3496  
69 272     272 1 1709 sub digest_file_b64 { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->b64digest }
  272         3481  
70 136     136 1 878 sub digest_file_b64u { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->b64udigest }
  136         1685  
71              
72             1;
73              
74             =pod
75              
76             =head1 NAME
77              
78             Crypt::Digest - Generic interface to hash/digest functions
79              
80             =head1 SYNOPSIS
81              
82             ### Functional interface:
83             use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u
84             digest_file digest_file_hex digest_file_b64 digest_file_b64u );
85              
86             my $data = 'data string';
87             my $filename = 'filename.dat';
88             open my $filehandle, '<:raw', $filename or die "cannot open $filename: $!";
89              
90             # calculate digest from string/buffer
91             my $digest_raw = digest_data('SHA256', $data);
92             my $digest_hex = digest_data_hex('SHA256', $data);
93             my $digest_b64 = digest_data_b64('SHA256', $data);
94             my $digest_b64u = digest_data_b64u('SHA256', $data);
95             # calculate digest from file
96             my $file_digest_raw = digest_file('SHA256', $filename);
97             my $file_digest_hex = digest_file_hex('SHA256', $filename);
98             my $file_digest_b64 = digest_file_b64('SHA256', $filename);
99             my $file_digest_b64u = digest_file_b64u('SHA256', $filename);
100             # calculate digest from filehandle
101             my $fh_digest_raw = digest_file('SHA256', $filehandle);
102              
103             ### OO interface:
104             use Crypt::Digest;
105              
106             my $d = Crypt::Digest->new('SHA1');
107             $d->add('any data');
108             $d->addfile('filename.dat');
109             $d->addfile($filehandle);
110             my $result_raw = $d->digest; # raw bytes
111             my $result_hex = $d->hexdigest; # hexadecimal form
112             my $result_b64 = $d->b64digest; # Base64 form
113             my $result_b64u = $d->b64udigest; # Base64 URL-safe form
114              
115             =head1 DESCRIPTION
116              
117             Provides an interface to various hash/digest algorithms.
118              
119             All functions and methods return raw bytes unless the method name explicitly
120             ends in C<_hex>, C<_b64>, or C<_b64u>. Invalid algorithm names croak.
121              
122             =head1 EXPORT
123              
124             Nothing is exported by default.
125              
126             You can export selected functions:
127              
128             use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u
129             digest_file digest_file_hex digest_file_b64 digest_file_b64u );
130              
131             Or all of them at once:
132              
133             use Crypt::Digest ':all';
134              
135             =head1 FUNCTIONS
136              
137             All functions take the algorithm name as the first argument. Supported values
138             are:
139              
140             'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160',
141             'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256',
142             'SHA384', 'SHA512', 'SHA512_224', 'SHA512_256', 'Tiger192', 'Whirlpool',
143             'SHA3_224', 'SHA3_256', 'SHA3_384', 'SHA3_512',
144             'Keccak224', 'Keccak256', 'Keccak384', 'Keccak512',
145             'BLAKE2b_160', 'BLAKE2b_256', 'BLAKE2b_384', 'BLAKE2b_512',
146             'BLAKE2s_128', 'BLAKE2s_160', 'BLAKE2s_224', 'BLAKE2s_256'
147              
148             (or any for which there is a Crypt::Digest:: module)
149              
150             =head2 digest_data
151              
152             Joins all arguments into a single string and returns the digest for
153             the selected algorithm encoded as a binary string.
154              
155             Data arguments are converted to byte strings using Perl's usual scalar
156             stringification. Defined scalars, including numbers and string-overloaded
157             objects, are accepted. C is treated as an empty string and may emit
158             Perl's usual "uninitialized value" warning. The same rules apply to
159             C, C, and C.
160              
161             my $digest_raw = digest_data('SHA256', 'data string');
162             #or
163             my $digest_raw = digest_data('SHA256', 'any data', 'more data', 'even more data');
164              
165             =head2 digest_data_hex
166              
167             Joins all arguments into a single string and returns the digest for
168             the selected algorithm encoded as a hexadecimal string.
169              
170             my $digest_hex = digest_data_hex('SHA256', 'data string');
171             #or
172             my $digest_hex = digest_data_hex('SHA256', 'any data', 'more data', 'even more data');
173              
174             =head2 digest_data_b64
175              
176             Joins all arguments into a single string and returns the digest for
177             the selected algorithm encoded as a Base64 string, B trailing '=' padding.
178              
179             my $digest_b64 = digest_data_b64('SHA256', 'data string');
180             #or
181             my $digest_b64 = digest_data_b64('SHA256', 'any data', 'more data', 'even more data');
182              
183             =head2 digest_data_b64u
184              
185             Joins all arguments into a single string and returns the digest for
186             the selected algorithm encoded as a Base64 URL-safe string (see RFC 4648 section 5).
187              
188             my $digest_b64url = digest_data_b64u('SHA256', 'data string');
189             #or
190             my $digest_b64url = digest_data_b64u('SHA256', 'any data', 'more data', 'even more data');
191              
192             =head2 digest_file
193              
194             Reads a file given by a filename or filehandle and returns its digest encoded as a binary string.
195              
196             my $digest_raw = digest_file('SHA256', 'filename.dat');
197             #or
198             my $filehandle = ...; # existing binary-mode filehandle
199             my $digest_raw = digest_file('SHA256', $filehandle);
200              
201             =head2 digest_file_hex
202              
203             Reads a file given by a filename or filehandle and returns its digest encoded as a hexadecimal string.
204              
205             my $digest_hex = digest_file_hex('SHA256', 'filename.dat');
206             #or
207             my $filehandle = ...; # existing binary-mode filehandle
208             my $digest_hex = digest_file_hex('SHA256', $filehandle);
209              
210             B The filehandle must be in binary mode before you pass it to C.
211              
212             =head2 digest_file_b64
213              
214             Reads a file given by a filename or filehandle and returns its digest encoded as a Base64 string, B trailing '=' padding.
215              
216             my $digest_b64 = digest_file_b64('SHA256', 'filename.dat');
217             #or
218             my $filehandle = ...; # existing binary-mode filehandle
219             my $digest_b64 = digest_file_b64('SHA256', $filehandle);
220              
221             =head2 digest_file_b64u
222              
223             Reads a file given by a filename or filehandle and returns its digest encoded as a Base64 URL-safe string (see RFC 4648 section 5).
224              
225             my $digest_b64url = digest_file_b64u('SHA256', 'filename.dat');
226             #or
227             my $filehandle = ...; # existing binary-mode filehandle
228             my $digest_b64url = digest_file_b64u('SHA256', $filehandle);
229              
230             =head1 METHODS
231              
232             Unless noted otherwise, assume C<$d> is an existing digest object created via
233             C, for example:
234              
235             my $d = Crypt::Digest->new('SHA256');
236              
237             =head2 new
238              
239             Constructor, returns a reference to the digest object.
240              
241             my $d = Crypt::Digest->new($name);
242             # $name could be: 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160',
243             # 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', 'SHA384',
244             # 'SHA512', 'SHA512_224', 'SHA512_256', 'SHA3_224', 'SHA3_256',
245             # 'SHA3_384', 'SHA3_512', 'Keccak224', 'Keccak256', 'Keccak384',
246             # 'Keccak512', 'BLAKE2b_160', 'BLAKE2b_256', 'BLAKE2b_384',
247             # 'BLAKE2b_512', 'BLAKE2s_128', 'BLAKE2s_160', 'BLAKE2s_224',
248             # 'BLAKE2s_256', 'Tiger192', 'Whirlpool'
249             #
250             # or any for which there is a Crypt::Digest:: module
251              
252             =head2 clone
253              
254             Creates a copy of the digest object state and returns a reference to the copy.
255              
256             $d->clone();
257              
258             =head2 reset
259              
260             Resets the digest object state and returns the digest object itself.
261              
262             $d->reset();
263              
264             =head2 add
265              
266             Appends all arguments to the message. Returns the digest object itself.
267              
268             Each argument is converted to bytes using Perl's usual scalar stringification.
269             Defined scalars, including numbers and string-overloaded objects, are
270             accepted. C is treated as an empty string and may emit Perl's usual
271             "uninitialized value" warning.
272              
273             $d->add('any data');
274             #or
275             $d->add('any data', 'more data', 'even more data');
276              
277             Note that all the following cases are equivalent:
278              
279             # case 1
280             $d->add('aa', 'bb', 'cc');
281              
282             # case 2
283             $d->add('aa');
284             $d->add('bb');
285             $d->add('cc');
286              
287             # case 3
288             $d->add('aabbcc');
289              
290             # case 4
291             $d->add('aa')->add('bb')->add('cc');
292              
293             =head2 addfile
294              
295             Reads a file or filehandle and appends its content to the message. Returns the
296             digest object itself.
297              
298             $d->addfile('filename.dat');
299             #or
300             my $filehandle = ...; # existing binary-mode filehandle
301             $d->addfile($filehandle);
302              
303             B The filehandle must be in binary mode before you pass it to C.
304              
305             =head2 hashsize
306              
307             Returns the length of calculated digest in bytes (e.g. 32 for SHA-256).
308              
309             $d->hashsize;
310             #or
311             Crypt::Digest->hashsize('SHA1');
312             #or
313             Crypt::Digest::hashsize('SHA1');
314              
315             =head2 digest
316              
317             Returns the binary digest (raw bytes).
318             The first call finalizes the digest object. Any later C,
319             C, C, C, C, or
320             C call will fail until you call C.
321              
322             my $result_raw = $d->digest();
323              
324             =head2 hexdigest
325              
326             Returns the digest encoded as a hexadecimal string.
327             Like C, the first call finalizes the digest object.
328              
329             my $result_hex = $d->hexdigest();
330              
331             =head2 b64digest
332              
333             Returns the digest encoded as a Base64 string with trailing C<=> padding.
334             B This padding style might differ from other C modules on
335             CPAN.
336             Like C, the first call finalizes the digest object.
337              
338             my $result_b64 = $d->b64digest();
339              
340             =head2 b64udigest
341              
342             Returns the digest encoded as a Base64 URL-safe string (see RFC 4648 section 5).
343             Like C, the first call finalizes the digest object.
344              
345             my $result_b64url = $d->b64udigest();
346              
347             =head1 SEE ALSO
348              
349             =over
350              
351             =item * L
352              
353             =item * L tries to be compatible with the L interface.
354              
355             =item * Check subclasses like L, L, ...
356              
357             =back
358              
359             =cut