File Coverage

blib/lib/Net/FCP/Util.pm
Criterion Covered Total %
statement 15 47 31.9
branch 0 4 0.0
condition n/a
subroutine 5 14 35.7
pod 9 9 100.0
total 29 74 39.1


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Net::FCP::Util - utility functions.
4              
5             =head1 SYNOPSIS
6              
7             use Net::FCP::Util;
8              
9              
10             =head1 DESCRIPTION
11              
12             =over 4
13              
14             =cut
15              
16             package Net::FCP::Util;
17              
18 1     1   4 use Carp ();
  1         2  
  1         21  
19 1     1   750 use Digest::SHA1;
  1         759  
  1         47  
20 1     1   670 use MIME::Base64 ();
  1         627  
  1         19  
21              
22 1     1   5 no warnings;
  1         2  
  1         37  
23              
24 1     1   4 use base Exporter::;
  1         1  
  1         800  
25              
26             @EXPORT_OK = qw(tolc touc xeh);
27              
28             =item touc $string
29              
30             Returns the uppercased version of the given identifier. Used internally to
31             map from e.g. URIError/KeyCollision to the form used in this module, i.e.
32             uri_error/key_collision etc.
33              
34             =cut
35              
36             sub touc($) {
37 0     0 1   local $_ = shift;
38 0           1 while s/((?:^|_)(?:svk|chk|uri)(?:_|$))/\U$1/;
39 0           s/(?:^|_)(.)/\U$1/g;
40 0           $_;
41             }
42              
43             =item tolc $string
44              
45             Returns the lowercased version of the given identifier. See C.
46              
47             =cut
48              
49             sub tolc($) {
50 0     0 1   local $_ = shift;
51 0           1 while s/(SVK|CHK|URI)([^_])/$1\_$2/i;
52 0           1 while s/([^_])(SVK|CHK|URI)/$1\_$2/i;
53 0           s/(?<=[a-z])(?=[A-Z])/_/g;
54 0           lc $_;
55             }
56              
57             =item xeh $number
58              
59             The opposite of C, i.e. returns the the number as hex string. Mainly
60             useful due to it's prototype of C<$>.
61              
62             =cut
63              
64             sub xeh($) {
65 0     0 1   sprintf "%x", $_[0];
66             }
67              
68             =item log2 $num[, $minlog]
69              
70             Calculate the (integer) log2 of a number, rounded up. If C<$minlog> is
71             given it will be the minimum value returned.
72              
73             =cut
74              
75             sub log2($;$) { # n, minlog
76 0 0   0 1   $_[0] && length sprintf "%$_[1]b", $_[0] - 1;
77             }
78             # the above line is much faster than the equivalent
79             # below, which illustrates a fine point of perl...
80             # my ($n, $b) = @_;
81             # $b++ while 1 << $b < $n;
82             # $b;
83              
84             =item encode_mpi $num
85              
86             Encode the given number as a multiple-precision number (2 byte bitlength + bytes)
87              
88             =cut
89              
90             sub encode_mpi($) {
91 0     0 1   my $num = pack "N", $_[0];
92 0           my $len = log2 $_[0], 1;
93 0           $num =~ s/^\x00+//;
94 0           pack "n a*", $len, $num;
95             }
96              
97             =item decode_base64 $string
98              
99             Decode freenet's perverted version of base64.
100              
101             =cut
102              
103             sub decode_base64($) {
104 0     0 1   my $s = shift;
105              
106 0           $s =~ y%~\-%+/%;
107 0           MIME::Base64::decode_base64 "$s======";
108             }
109              
110             =item encode_base64 $data
111              
112             Encode into freenet's perverted version of base64.
113              
114             =cut
115              
116             sub encode_base64($) {
117 0     0 1   my $s = MIME::Base64::encode_base64 shift, "";
118 0           $s =~ s/=+$//;
119 0           $s =~ y%+/%~\-%;
120 0           $s;
121             }
122              
123             =item generate_chk_hash $metadata, $data
124              
125             Generate and return they hash portion (the part after the comma, the
126             crypto key) that would be used in the CHK (as binary). This can be used to
127             verify contents of a CHK, since this key is a hash over the data.
128              
129             (This function assumes a 128 bit key, which seems standard in freenet).
130              
131             =cut
132              
133             sub generate_chk_hash($$) {
134 0     0 1   my $d = new Digest::SHA1;
135              
136 0           $d->add ($_[0]);
137 0           $d->add ($_[1]);
138 0           $d = $d->digest;
139              
140 0           my $k = new Digest::SHA1;
141 0           $k->add ("\x00" x 1); # only one iteration
142 0           $k->add ($d);
143            
144 0           substr $k->digest, 0, 16; # extract leading 128 bit
145             }
146              
147             =item extract_chk_hash $uri
148              
149             Extract the hash portion (the part after the comma, the crypto key) of a
150             CHK (in binary). Useful to compare against the output of generate_chk_key.
151              
152             =cut
153              
154             sub extract_chk_hash($) {
155 0 0   0 1   $_[0] =~ /CHK\@[a-zA-Z0-9~\-]{31},([a-zA-Z0-9~\-]{22})/
156             or Carp::croak "unable to parse CHK key from '$_[0]'";
157              
158 0           decode_base64 $1;
159             }
160              
161             =back
162              
163             =head1 SEE ALSO
164              
165             L.
166              
167             =head1 BUGS
168              
169             Not heavily tested.
170              
171             =head1 AUTHOR
172              
173             Marc Lehmann
174             http://home.schmorp.de/
175              
176             =cut
177              
178             1;
179