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