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 57     57   2901189 use strict;
  57         117  
  57         1701  
4 57     57   346 use warnings;
  57         77  
  57         7166  
5             our $VERSION = '0.088_004';
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 57     57   322 use Carp;
  57         97  
  57         3628  
13             $Carp::Internal{(__PACKAGE__)}++;
14 57     57   13840 use CryptX;
  57         118  
  57         24886  
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 1193     1193 1 129725 my ($self, $file) = @_;
35              
36 1193         1593 my ($handle, $close_handle);
37 1193 100 100     5962 if (ref($file) && eval { defined fileno($file) }) {
  135 100 66     542  
38 134         184 $handle = $file;
39             }
40             elsif (defined($file) && !ref($file)) {
41 1058 50       43708 open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!";
42 1058         2689 binmode($handle);
43 1058         2070 $close_handle = 1;
44             }
45             else {
46 1         164 croak "FATAL: invalid handle";
47             }
48              
49 1192         1482 my $n;
50 1192         1724 my $buf = "";
51             {
52 1192         1346 local $SIG{__DIE__} = \&CryptX::_croak;
  1192         5318  
53 1192         27193 while (($n = read($handle, $buf, 32*1024))) {
54 1192         37724 $self->add($buf)
55             }
56 1192 50       4233 croak "FATAL: read failed: $!" unless defined $n;
57             }
58 1192 100       10423 close($handle) if $close_handle;
59              
60 1192         15641 return $self;
61             }
62              
63 0     0   0 sub CLONE_SKIP { 1 } # prevent cloning
64              
65             ### FUNCTIONS
66              
67 264     264 1 1181 sub digest_file { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->digest }
  264         2357  
68 266     266 1 1174 sub digest_file_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->hexdigest }
  266         2579  
69 264     264 1 1181 sub digest_file_b64 { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->b64digest }
  264         2616  
70 132     132 1 600 sub digest_file_b64u { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->b64udigest }
  132         1322  
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             Please note that all functions take as its first argument the algorithm name, supported values are:
138              
139             'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160',
140             'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256',
141             'SHA384', 'SHA512', 'SHA512_224', 'SHA512_256', 'Tiger192', 'Whirlpool',
142             'SHA3_224', 'SHA3_256', 'SHA3_384', 'SHA3_512',
143             'Keccak224', 'Keccak256', 'Keccak384', 'Keccak512',
144             'BLAKE2b_160', 'BLAKE2b_256', 'BLAKE2b_384', 'BLAKE2b_512',
145             'BLAKE2s_128', 'BLAKE2s_160', 'BLAKE2s_224', 'BLAKE2s_256'
146              
147             (simply any for which there is Crypt::Digest:: module)
148              
149             =head2 digest_data
150              
151             Logically joins all arguments into a single string, and returns the digest for
152             the selected algorithm encoded as a binary string.
153              
154             Data arguments are converted to byte strings using Perl's usual scalar
155             stringification. Defined scalars, including numbers and string-overloaded
156             objects, are accepted. C is treated as an empty string and may emit
157             Perl's usual "uninitialized value" warning. The same rules apply to
158             C, C, and C.
159              
160             my $digest_raw = digest_data('SHA256', 'data string');
161             #or
162             my $digest_raw = digest_data('SHA256', 'any data', 'more data', 'even more data');
163              
164             =head2 digest_data_hex
165              
166             Logically joins all arguments into a single string, and returns the digest for
167             the selected algorithm encoded as a hexadecimal string.
168              
169             my $digest_hex = digest_data_hex('SHA256', 'data string');
170             #or
171             my $digest_hex = digest_data_hex('SHA256', 'any data', 'more data', 'even more data');
172              
173             =head2 digest_data_b64
174              
175             Logically joins all arguments into a single string, and returns the digest for
176             the selected algorithm encoded as a Base64 string, B trailing '=' padding.
177              
178             my $digest_b64 = digest_data_b64('SHA256', 'data string');
179             #or
180             my $digest_b64 = digest_data_b64('SHA256', 'any data', 'more data', 'even more data');
181              
182             =head2 digest_data_b64u
183              
184             Logically joins all arguments into a single string, and returns the digest for
185             the selected algorithm encoded as a Base64 URL Safe string (see RFC 4648 section 5).
186              
187             my $digest_b64url = digest_data_b64u('SHA256', 'data string');
188             #or
189             my $digest_b64url = digest_data_b64u('SHA256', 'any data', 'more data', 'even more data');
190              
191             =head2 digest_file
192              
193             Reads file (defined by filename or filehandle) content, and returns its digest encoded as a binary string.
194              
195             my $digest_raw = digest_file('SHA256', 'filename.dat');
196             #or
197             my $filehandle = ...; # existing binary-mode filehandle
198             my $digest_raw = digest_file('SHA256', $filehandle);
199              
200             =head2 digest_file_hex
201              
202             Reads file (defined by filename or filehandle) content, and returns its digest encoded as a hexadecimal string.
203              
204             my $digest_hex = digest_file_hex('SHA256', 'filename.dat');
205             #or
206             my $filehandle = ...; # existing binary-mode filehandle
207             my $digest_hex = digest_file_hex('SHA256', $filehandle);
208              
209             B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method.
210              
211             =head2 digest_file_b64
212              
213             Reads file (defined by filename or filehandle) content, and returns its digest encoded as a Base64 string, B trailing '=' padding.
214              
215             my $digest_b64 = digest_file_b64('SHA256', 'filename.dat');
216             #or
217             my $filehandle = ...; # existing binary-mode filehandle
218             my $digest_b64 = digest_file_b64('SHA256', $filehandle);
219              
220             =head2 digest_file_b64u
221              
222             Reads file (defined by filename or filehandle) content, and returns its digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
223              
224             my $digest_b64url = digest_file_b64u('SHA256', 'filename.dat');
225             #or
226             my $filehandle = ...; # existing binary-mode filehandle
227             my $digest_b64url = digest_file_b64u('SHA256', $filehandle);
228              
229             =head1 METHODS
230              
231             Unless noted otherwise, assume C<$d> is an existing digest object created via
232             C, for example:
233              
234             my $d = Crypt::Digest->new('SHA256');
235              
236             =head2 new
237              
238             Constructor, returns a reference to the digest object.
239              
240             my $d = Crypt::Digest->new($name);
241             # $name could be: 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160',
242             # 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', 'SHA384',
243             # 'SHA512', 'SHA512_224', 'SHA512_256', 'SHA3_224', 'SHA3_256',
244             # 'SHA3_384', 'SHA3_512', 'Keccak224', 'Keccak256', 'Keccak384',
245             # 'Keccak512', 'BLAKE2b_160', 'BLAKE2b_256', 'BLAKE2b_384',
246             # 'BLAKE2b_512', 'BLAKE2s_128', 'BLAKE2s_160', 'BLAKE2s_224',
247             # 'BLAKE2s_256', 'Tiger192', 'Whirlpool'
248             #
249             # simply any for which there is Crypt::Digest:: module
250              
251             =head2 clone
252              
253             Creates a copy of the digest object state and returns a reference to the copy.
254              
255             $d->clone();
256              
257             =head2 reset
258              
259             Reinitialize the digest object state and returns a reference to the digest object.
260              
261             $d->reset();
262              
263             =head2 add
264              
265             All arguments are appended to the message we calculate digest for.
266             The return value is 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             The content of the file (or filehandle) is appended to the message we calculate digest for.
296             The return value is the 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 You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method.
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, B trailing '=' padding (B this padding
334             style might differ from other Digest:: modules on CPAN).
335             Like C, the first call finalizes the digest object.
336              
337             my $result_b64 = $d->b64digest();
338              
339             =head2 b64udigest
340              
341             Returns the digest encoded as a Base64 URL Safe string (see RFC 4648 section 5).
342             Like C, the first call finalizes the digest object.
343              
344             my $result_b64url = $d->b64udigest();
345              
346             =head1 SEE ALSO
347              
348             =over
349              
350             =item * L
351              
352             =item * L tries to be compatible with L interface.
353              
354             =item * Check subclasses like L, L, ...
355              
356             =back
357              
358             =cut