File Coverage

blib/lib/Crypt/Rhash.pm
Criterion Covered Total %
statement 167 176 94.8
branch 13 32 40.6
condition 4 7 57.1
subroutine 54 56 96.4
pod 14 16 87.5
total 252 287 87.8


line stmt bran cond sub pod time code
1             package Crypt::Rhash;
2              
3 3     3   206018 use 5.006001;
  3         39  
4 3     3   15 use strict;
  3         6  
  3         87  
5 3     3   15 use warnings;
  3         4  
  3         469  
6              
7             require Exporter;
8             our @ISA = (qw(Exporter));
9              
10             # possible tags for export
11             our %EXPORT_TAGS = (
12             Functions => [qw(raw2hex raw2base32 raw2base64)],
13             Constants => [qw(RHASH_CRC32 RHASH_CRC32C RHASH_MD4 RHASH_MD5 RHASH_SHA1
14             RHASH_TIGER RHASH_TTH RHASH_BTIH RHASH_ED2K RHASH_AICH RHASH_WHIRLPOOL
15             RHASH_RIPEMD160 RHASH_GOST RHASH_GOST_CRYPTOPRO RHASH_HAS160
16             RHASH_SNEFRU128 RHASH_SNEFRU256 RHASH_SHA224 RHASH_SHA256
17             RHASH_SHA384 RHASH_SHA512 RHASH_EDONR256 RHASH_EDONR512
18             RHASH_SHA3_224 RHASH_SHA3_256 RHASH_SHA3_384 RHASH_SHA3_512 RHASH_ALL)]
19             );
20              
21             Exporter::export_tags( );
22             Exporter::export_ok_tags( qw(Functions Constants) );
23              
24             our $VERSION = '0.95';
25              
26             require XSLoader;
27             XSLoader::load('Crypt::Rhash', $VERSION);
28              
29             ##############################################################################
30             # ids of hash functions
31 3     3   22 use constant RHASH_CRC32 => 0x01;
  3         5  
  3         372  
32 3     3   19 use constant RHASH_MD4 => 0x02;
  3         6  
  3         146  
33 3     3   17 use constant RHASH_MD5 => 0x04;
  3         5  
  3         143  
34 3     3   38 use constant RHASH_SHA1 => 0x08;
  3         6  
  3         151  
35 3     3   17 use constant RHASH_TIGER => 0x10;
  3         6  
  3         141  
36 3     3   17 use constant RHASH_TTH => 0x20;
  3         13  
  3         169  
37 3     3   26 use constant RHASH_BTIH => 0x40;
  3         13  
  3         155  
38 3     3   33 use constant RHASH_ED2K => 0x80;
  3         7  
  3         141  
39 3     3   18 use constant RHASH_AICH => 0x100;
  3         4  
  3         142  
40 3     3   18 use constant RHASH_WHIRLPOOL => 0x200;
  3         4  
  3         141  
41 3     3   22 use constant RHASH_RIPEMD160 => 0x400;
  3         15  
  3         170  
42 3     3   18 use constant RHASH_GOST => 0x800;
  3         5  
  3         145  
43 3     3   17 use constant RHASH_GOST_CRYPTOPRO => 0x1000;
  3         5  
  3         154  
44 3     3   17 use constant RHASH_HAS160 => 0x2000;
  3         10  
  3         142  
45 3     3   16 use constant RHASH_SNEFRU128 => 0x4000;
  3         6  
  3         140  
46 3     3   27 use constant RHASH_SNEFRU256 => 0x8000;
  3         16  
  3         133  
47 3     3   16 use constant RHASH_SHA224 => 0x10000;
  3         6  
  3         173  
48 3     3   18 use constant RHASH_SHA256 => 0x20000;
  3         6  
  3         135  
49 3     3   17 use constant RHASH_SHA384 => 0x40000;
  3         6  
  3         163  
50 3     3   20 use constant RHASH_SHA512 => 0x80000;
  3         5  
  3         176  
51 3     3   20 use constant RHASH_EDONR256 => 0x100000;
  3         6  
  3         134  
52 3     3   16 use constant RHASH_EDONR512 => 0x200000;
  3         3  
  3         143  
53 3     3   17 use constant RHASH_SHA3_224 => 0x0400000;
  3         14  
  3         133  
54 3     3   17 use constant RHASH_SHA3_256 => 0x0800000;
  3         19  
  3         143  
55 3     3   17 use constant RHASH_SHA3_384 => 0x1000000;
  3         12  
  3         141  
56 3     3   16 use constant RHASH_SHA3_512 => 0x2000000;
  3         6  
  3         122  
57 3     3   20 use constant RHASH_CRC32C => 0x4000000;
  3         4  
  3         218  
58 3     3   19 use constant RHASH_ALL => 0x7FFFFFF;
  3         22  
  3         1964  
59              
60             ##############################################################################
61             # Rhash class methods
62              
63             # Rhash object constructor
64             sub new
65             {
66 5 50   5 0 310 my $hash_id = $_[1] or die "hash_id not specified";
67 5 50       101 my $context = rhash_init(scalar($hash_id)) or return undef;
68 5         17 my $self = {
69             context => $context,
70             };
71 5         21 return bless $self;
72             }
73              
74             # destructor
75             sub DESTROY($)
76             {
77 3     3   6 my $self = shift;
78             # the 'if' added as workaround for perl 'global destruction' bug
79             # ($self->{context} can disappear on global destruction)
80 3 50       25 rhash_free($self->{context}) if $self->{context};
81             }
82              
83             sub update($$)
84             {
85 4     4 1 17 my $self = shift;
86 4         8 my $message = shift;
87 4         64 rhash_update($self->{context}, $message);
88 4         18 return $self;
89             }
90              
91             sub update_fd($$;$$)
92             {
93 3     3 1 7 my ($self, $fd, $start, $size) = @_;
94 3         5 my $res = 0;
95 3         5 my $num = 0;
96              
97 3         7 binmode($fd);
98 3 100       8 if(defined($start)) {
99 1 50       12 seek($fd, scalar($start), 0) or return undef;
100             }
101              
102 3         6 my $data;
103 3 100       8 if(defined($size)) {
104 1         4 for(my $left = scalar($size); $left > 0; $left -= 8192) {
105 1 50       21 ($res = read($fd, $data,
    50          
106             ($left < 8192 ? $left : 8192))) || last;
107 1         6 rhash_update($self->{context}, $data);
108 1         3 $num += $res;
109             }
110             } else {
111 2         41 while( ($res = read($fd, $data, 8192)) ) {
112 2         12 rhash_update($self->{context}, $data);
113 2         26 $num += $res;
114             }
115             }
116              
117 3 50       29 return (defined($res) ? $num : undef); # return undef on read error
118             }
119              
120             sub update_file($$;$$)
121             {
122 2     2 1 10 my ($self, $file, $start, $size) = @_;
123 2 50       72 open(my $fd, "<", $file) or return undef;
124 2         9 my $res = $self->update_fd($fd, $start, $size);
125 2         22 close($fd);
126 2         15 return $res;
127             }
128              
129             sub final($)
130             {
131 3     3 1 5 my $self = shift;
132 3         312 rhash_final($self->{context});
133 3         12 return $self;
134             }
135              
136             sub reset($)
137             {
138 3     3 1 7 my $self = shift;
139 3         14 rhash_reset($self->{context});
140 3         9 return $self;
141             }
142              
143             sub hashed_length($)
144             {
145 1     1 1 3 my $self = shift;
146 1         7 return rhash_get_hashed_length($self->{context});
147             }
148              
149             sub hash_id($)
150             {
151 1     1 1 3 my $self = shift;
152 1         8 return rhash_get_hash_id($self->{context});
153             }
154              
155             ##############################################################################
156             # Hash formatting functions
157              
158             # printing constants
159 3     3   25 use constant RHPR_DEFAULT => 0x0;
  3         6  
  3         164  
160 3     3   17 use constant RHPR_RAW => 0x1;
  3         5  
  3         147  
161 3     3   18 use constant RHPR_HEX => 0x2;
  3         5  
  3         135  
162 3     3   18 use constant RHPR_BASE32 => 0x3;
  3         5  
  3         132  
163 3     3   23 use constant RHPR_BASE64 => 0x4;
  3         5  
  3         126  
164 3     3   15 use constant RHPR_UPPERCASE => 0x8;
  3         6  
  3         179  
165 3     3   20 use constant RHPR_REVERSE => 0x10;
  3         5  
  3         1839  
166              
167             sub hash($;$$)
168             {
169 38     38 1 75 my $self = shift;
170 38   100     103 my $hash_id = scalar(shift) || 0;
171 38   100     121 my $print_flags = scalar(shift) || RHPR_DEFAULT;
172 38         348 return rhash_print($self->{context}, $hash_id, $print_flags);
173             }
174              
175             sub hash_base32($;$)
176             {
177 1     1 1 4 hash($_[0], $_[1], RHPR_BASE32);
178             }
179              
180             sub hash_base64($;$)
181             {
182 0     0 1 0 hash($_[0], $_[1], RHPR_BASE64);
183             }
184              
185             sub hash_hex($;$)
186             {
187 2     2 1 7 hash($_[0], $_[1], RHPR_HEX);
188             }
189              
190             sub hash_rhex($;$)
191             {
192 1     1 1 4 hash($_[0], $_[1], RHPR_HEX | RHPR_REVERSE);
193             }
194              
195             sub hash_raw($;$)
196             {
197 1     1 0 4 hash($_[0], $_[1], RHPR_RAW);
198             }
199              
200             sub magnet_link($;$$)
201             {
202 3     3 1 9 my ($self, $filename, $hash_mask) = @_;
203 3         31 return rhash_print_magnet($self->{context}, $filename, $hash_mask);
204             }
205              
206             our $AUTOLOAD;
207              
208             # report error if a script called unexisting method/field
209             sub AUTOLOAD
210             {
211 0     0   0 my ($self, $field, $type, $pkg) = ($_[0], $AUTOLOAD, undef, __PACKAGE__);
212 0         0 $field =~ s/.*://;
213 0 0       0 die "function $field does not exist" if $field =~ /^(rhash_|raw2)/;
214 0 0       0 die "no arguments specified to $field()" if !@_;
215 0 0       0 die "the $field() argument is undefined" if !defined $self;
216              
217 0 0 0     0 ($type = ref($self)) && $type eq $pkg || die "the $field() argument is not a $pkg reference";
218 0 0       0 my $text = (exists $self->{$field} ? "is not accessible" : "does not exist");
219 0         0 die "the method $field() $text in the class $pkg";
220             }
221              
222             # static functions
223              
224             sub msg($$)
225             {
226 1     1 1 4861 my ($hash_id, $msg) = @_;
227 1         11 my $raw = rhash_msg_raw($hash_id, $msg); # get binary hash
228 1 50       10 return (is_base32($hash_id) ? raw2base32($raw) : raw2hex($raw));
229             }
230              
231             1;
232             __END__