File Coverage

blib/lib/Crypt/SSSS/Message.pm
Criterion Covered Total %
statement 62 62 100.0
branch 4 6 66.6
condition 1 2 50.0
subroutine 10 10 100.0
pod 0 6 0.0
total 77 86 89.5


line stmt bran cond sub pod time code
1             package Crypt::SSSS::Message;
2              
3 2     2   772 use strict;
  2         4  
  2         50  
4 2     2   10 use warnings;
  2         2  
  2         1210  
5              
6             require Carp;
7              
8             sub new {
9 37     37 0 977 my $class = shift;
10 37         69 my %args = @_;
11              
12 37 50       84 Carp::croak('Missed "p" argument') unless $args{p};
13              
14             bless {
15             _data => $args{data} || [],
16             _p => $args{p},
17 37   50     202 _size => _determine_chunk_size($args{p} - 1)
18             }, $class;
19             }
20              
21             sub build_from_binary {
22 17     17 0 29 my ($class, $p, $string) = @_;
23              
24 17         39 my $self = $class->new(p => $p);
25              
26 17         24 my $rdata = 0;
27 17         18 my $rsize = 0;
28              
29 17         45 my @chunks = unpack 'C*', $string;
30              
31 17         29 my $size = $self->{_size};
32              
33 17         18 my $smask = 0;
34 17         88 $smask = ($smask << 1) | 1 for (1 .. $size);
35              
36 17         43 while (@chunks > 0) {
37 48         75 $rdata = $rdata << 8 | shift @chunks;
38 48         58 $rsize += 8;
39              
40 48         116 while ($rsize >= $size) {
41 30         39 $rsize -= $size;
42              
43 30         35 my $mask = $smask << $rsize;
44 30         69 $self->push_data(($rdata & $mask) >> $rsize);
45 30         108 $rdata &= ~$mask;
46             }
47             }
48              
49 17         51 $self;
50             }
51              
52             sub push_data {
53 61     61 0 1887 my ($self, $data) = @_;
54              
55 61 50       173 Carp::croak('Data greater than p') if $data > $self->{_p};
56 61         96 push @{$self->{_data}}, $data;
  61         194  
57             }
58              
59             sub binary {
60 19     19 0 45 my $self = shift;
61              
62 19         25 my $rsize = 0;
63 19         26 my $rdata = 0x00;
64              
65 19         21 my $str;
66              
67 19         23 foreach my $lchunk (@{$self->{_data}}) {
  19         46  
68 34         47 my $size = $self->{_size};
69              
70 34         53 my $chunk = $rdata << $size | $lchunk;
71 34         39 $size += $rsize;
72              
73 34         81 while ($size >= 8) {
74 37         40 $size -= 8;
75 37         43 my $mask = 0xff << $size;
76              
77 37         45 my $data = ($chunk & $mask) >> $size;
78 37         45 $chunk &= ~$mask;
79              
80 37         105 $str .= pack 'C', $data;
81             }
82 34         39 $rsize = $size;
83 34         60 $rdata = $chunk;
84             }
85              
86 19 100       63 $str .= pack 'C', ($rdata << 8 - $rsize) if $rsize;
87              
88 19         88 $str;
89             }
90              
91             sub get_data {
92 30     30 0 498 my $self = shift;
93 30         148 return $self->{_data};
94             }
95              
96             sub get_p {
97 8     8 0 39 my $self = shift;
98 8         27 return $self->{_p};
99             }
100              
101             # Hope we will not have p greater than dword can have
102             # Same as log2
103             sub _sig_bit {
104 37     37   44 my $x = shift;
105              
106 37         43 my $i = 0;
107 37         83 while ($x) {
108 379         381 $x >>= 1;
109 379         655 $i++;
110             };
111 37         197 $i;
112             }
113              
114             sub _determine_chunk_size {
115 37     37   48 my ($p) = @_;
116              
117 37         68 _sig_bit($p);
118             }
119              
120              
121             1;