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   1033 use strict;
  2         4  
  2         65  
4 2     2   12 use warnings;
  2         3  
  2         1479  
5              
6             require Carp;
7              
8             sub new {
9 37     37 0 738 my $class = shift;
10 37         71 my %args = @_;
11              
12 37 50       86 Carp::croak('Missed "p" argument') unless $args{p};
13              
14             bless {
15             _data => $args{data} || [],
16             _p => $args{p},
17 37   50     196 _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         46 my $self = $class->new(p => $p);
25              
26 17         24 my $rdata = 0;
27 17         19 my $rsize = 0;
28              
29 17         53 my @chunks = unpack 'C*', $string;
30              
31 17         31 my $size = $self->{_size};
32              
33 17         18 my $smask = 0;
34 17         92 $smask = ($smask << 1) | 1 for (1 .. $size);
35              
36 17         52 while (@chunks > 0) {
37 48         71 $rdata = $rdata << 8 | shift @chunks;
38 48         64 $rsize += 8;
39              
40 48         123 while ($rsize >= $size) {
41 30         42 $rsize -= $size;
42              
43 30         40 my $mask = $smask << $rsize;
44 30         75 $self->push_data(($rdata & $mask) >> $rsize);
45 30         109 $rdata &= ~$mask;
46             }
47             }
48              
49 17         52 $self;
50             }
51              
52             sub push_data {
53 61     61 0 1801 my ($self, $data) = @_;
54              
55 61 50       146 Carp::croak('Data greater than p') if $data > $self->{_p};
56 61         86 push @{$self->{_data}}, $data;
  61         199  
57             }
58              
59             sub binary {
60 19     19 0 51 my $self = shift;
61              
62 19         26 my $rsize = 0;
63 19         28 my $rdata = 0x00;
64              
65 19         23 my $str;
66              
67 19         26 foreach my $lchunk (@{$self->{_data}}) {
  19         56  
68 34         55 my $size = $self->{_size};
69              
70 34         54 my $chunk = $rdata << $size | $lchunk;
71 34         48 $size += $rsize;
72              
73 34         87 while ($size >= 8) {
74 37         70 $size -= 8;
75 37         46 my $mask = 0xff << $size;
76              
77 37         52 my $data = ($chunk & $mask) >> $size;
78 37         43 $chunk &= ~$mask;
79              
80 37         345 $str .= pack 'C', $data;
81             }
82 34         44 $rsize = $size;
83 34         59 $rdata = $chunk;
84             }
85              
86 19 100       66 $str .= pack 'C', ($rdata << 8 - $rsize) if $rsize;
87              
88 19         101 $str;
89             }
90              
91             sub get_data {
92 30     30 0 488 my $self = shift;
93 30         150 return $self->{_data};
94             }
95              
96             sub get_p {
97 8     8 0 45 my $self = shift;
98 8         38 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         42 my $i = 0;
107 37         78 while ($x) {
108 379         387 $x >>= 1;
109 379         679 $i++;
110             };
111 37         205 $i;
112             }
113              
114             sub _determine_chunk_size {
115 37     37   50 my ($p) = @_;
116              
117 37         66 _sig_bit($p);
118             }
119              
120              
121             1;