File Coverage

blib/lib/Crypt/Trifid.pm
Criterion Covered Total %
statement 75 75 100.0
branch 4 8 50.0
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 90 94 95.7


line stmt bran cond sub pod time code
1             package Crypt::Trifid;
2              
3             $Crypt::Trifid::VERSION = '0.11';
4             $Crypt::Trifid::AUTHORITY = 'cpan:MANWAR';
5              
6             =head1 NAME
7              
8             Crypt::Trifid - Interface to the Trifid cipher.
9              
10             =head1 VERSION
11              
12             Version 0.11
13              
14             =cut
15              
16 4     4   61871 use 5.006;
  4         27  
17 4     4   2159 use Data::Dumper;
  4         23017  
  4         248  
18 4     4   1603 use Crypt::Trifid::Utils qw(generate_chart);
  4         9  
  4         236  
19              
20 4     4   1991 use Moo;
  4         41447  
  4         16  
21 4     4   11439 use namespace::autoclean;
  4         44258  
  4         14  
22              
23             has 'chart' => (is => 'ro', default => sub { generate_chart(); });
24              
25             =head1 DESCRIPTION
26              
27             In classical cryptography, the trifid cipher is a cipher invented around 1901 by
28             Felix Delastelle, which extends the concept of the bifid cipher to a third
29             dimension, allowing each symbol to be fractionated into 3 elements instead of two.
30              
31             While the bifid uses the Polybius square to turn each symbol into coordinates on
32             a 5x5 (or 6x6) square, the trifid turns them into coordinates on a 3x3x3 cube.
33              
34             As with the bifid, this is then combined with transposition to achieve diffusion.
35              
36             However a higher degree of diffusion is achieved because each output symbol
37             depends on 3 input symbols instead of two.
38              
39             Thus the trifid was the first practical trigraphic substitution.
40              
41             Source: L
42              
43             =head1 SYNOPSIS
44              
45             use strict; use warnings;
46             use Crypt::Trifid;
47              
48             my $crypt = Crypt::Trifid->new;
49             my $message = 'TRIFID';
50             my $encoded = $crypt->encode($message);
51             my $decoded = $crypt->decode($encoded);
52              
53             print "Encoded message: [$encoded]\n";
54             print "Decoded message: [$decoded]\n";
55              
56             =head1 METHODS
57              
58             =head2 encode($message)
59              
60             It takes message as scalar string and returns the encoded message.
61              
62             use strict; use warnings;
63             use Crypt::Trifid;
64              
65             my $crypt = Crypt::Trifid->new;
66             my $message = 'TRIFID';
67             my $encoded = $crypt->encode($message);
68              
69             print "Encoded message: [$encoded]\n";
70              
71             =cut
72              
73             sub encode {
74 3     3 1 16 my ($self, $message) = @_;
75              
76 3 50       11 die "ERROR: Missing message.\n" unless defined $message;
77 3 50       7 die "ERROR: Invalid message.\n" if ref($message);
78              
79 3         12 my $chart = $self->chart;
80 3         9 my @values = _encode($message, $chart);
81              
82 3         5 my $start = 0;
83 3         6 my $encoded = '';
84 3         47 my $_chart = { reverse %$chart };
85              
86 3         10 while ($start < scalar(@values)) {
87 18         25 my $end = $start + 2;
88 18         34 my $value = join '', @values[$start..$end];
89 18         27 $encoded .= $_chart->{$value};
90 18         45 $start = $end + 1;
91             }
92              
93 3         21 return $encoded;
94             }
95              
96             =head2 decode($encoded_message)
97              
98             It takes an encoded message as scalar string and returns the decoded message.
99              
100             use strict; use warnings;
101             use Crypt::Trifid;
102              
103             my $crypt = Crypt::Trifid->new;
104             my $message = 'TRIFID';
105             my $encoded = $crypt->encode($message);
106             my $decoded = $crypt->decode($encoded);
107              
108             print "Encoded message: [$encoded]\n";
109             print "Decoded message: [$decoded]\n";
110              
111             =cut
112              
113             sub decode {
114 2     2 1 12 my ($self, $message) = @_;
115              
116 2 50       4 die "ERROR: Missing message.\n" unless defined $message;
117 2 50       5 die "ERROR: Invalid message.\n" if ref($message);
118              
119 2         4 my $chart = $self->chart;
120 2         21 my $_chart = { reverse %$chart };
121 2         38 my @nodes = _decode($message, $chart);
122              
123 2         4 my $index = 0;
124 2         3 my $_chars = [];
125 2         2 my $i = 0;
126 2         5 my $j = scalar(@nodes)/3;
127 2         6 while ($index < scalar(@nodes)) {
128 6         23 push @{$_chars->[$i]}, @nodes[$index..($index+$j-1)];
  6         21  
129 6         9 $index += $j;
130 6         9 $i++;
131             }
132              
133 2         4 my $decoded = '';
134 2         4 foreach (1..$j) {
135 12         19 my $x = $_chars->[0]->[$_-1];
136 12         13 my $y = $_chars->[1]->[$_-1];
137 12         13 my $z = $_chars->[2]->[$_-1];
138 12         25 $decoded .= $_chart->{sprintf("%d%d%d", $x, $y, $z)};
139             }
140              
141 2         18 return $decoded;
142             }
143              
144             #
145             #
146             # PRIVATE METHODS
147              
148             sub _encode {
149 3     3   7 my ($message, $chart) = @_;
150              
151 3         15 my @chars = split //,$message;
152 3         6 my $chars = [];
153 3         5 my $column = 0;
154 3         6 foreach (@chars) {
155 18         30 my $node = $chart->{uc($_)};
156 18         26 my @node = split //,$node;
157              
158 18         26 $chars->[0]->[$column] = $node[0];
159 18         24 $chars->[1]->[$column] = $node[1];
160 18         22 $chars->[2]->[$column] = $node[2];
161              
162 18         25 $column++;
163             }
164              
165 3         4 my $values = join '', @{$chars->[0]}, @{$chars->[1]}, @{$chars->[2]};
  3         7  
  3         4  
  3         9  
166 3         35 my @values = split //, $values;
167              
168 3         30 return @values;
169             }
170              
171             sub _decode {
172 2     2   4 my ($message, $chart) = @_;
173              
174 2         9 my @chars = split //,$message;
175 2         3 my $node = '';
176 2         4 foreach (@chars) {
177 12         16 my $_node = $chart->{uc($_)};
178 12         26 $node .= sprintf("%d", $_node);
179             }
180              
181 2         15 my @nodes = split //, $node;
182              
183 2         21 return @nodes;
184             }
185              
186             =head1 AUTHOR
187              
188             Mohammad S Anwar, C<< >>
189              
190             =head1 REPOSITORY
191              
192             L
193              
194             =head1 BUGS
195              
196             Please report any bugs/feature requests to C or
197             through the web interface at L.
198             I will be notified & then you'll automatically be notified of progress on your bug
199             as I make changes.
200              
201             =head1 SUPPORT
202              
203             You can find documentation for this module with the perldoc command.
204              
205             perldoc Crypt::Trifid
206              
207             You can also look for information at:
208              
209             =over 4
210              
211             =item * RT: CPAN's request tracker
212              
213             L
214              
215             =item * AnnoCPAN: Annotated CPAN documentation
216              
217             L
218              
219             =item * CPAN Ratings
220              
221             L
222              
223             =item * Search CPAN
224              
225             L
226              
227             =back
228              
229             =head1 LICENSE AND COPYRIGHT
230              
231             Copyright (C) 2014 - 2017 Mohammad S Anwar.
232              
233             This program is free software; you can redistribute it and/or modify it under
234             the terms of the the Artistic License (2.0). You may obtain a copy of the full
235             license at:
236              
237             L
238              
239             Any use, modification, and distribution of the Standard or Modified Versions is
240             governed by this Artistic License.By using, modifying or distributing the Package,
241             you accept this license. Do not use, modify, or distribute the Package, if you do
242             not accept this license.
243              
244             If your Modified Version has been derived from a Modified Version made by someone
245             other than you,you are nevertheless required to ensure that your Modified Version
246             complies with the requirements of this license.
247              
248             This license does not grant you the right to use any trademark, service mark,
249             tradename, or logo of the Copyright Holder.
250              
251             This license includes the non-exclusive, worldwide, free-of-charge patent license
252             to make, have made, use, offer to sell, sell, import and otherwise transfer the
253             Package with respect to any patent claims licensable by the Copyright Holder that
254             are necessarily infringed by the Package. If you institute patent litigation
255             (including a cross-claim or counterclaim) against any party alleging that the
256             Package constitutes direct or contributory patent infringement,then this Artistic
257             License to you shall terminate on the date that such litigation is filed.
258              
259             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND
260             CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
261             WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
262             NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS
263             REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT,
264             INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE
265             OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266              
267             =cut
268              
269             1; # End of Crypt::Trifid