File Coverage

blib/lib/Crypt/OOEnigma/Reflector.pm
Criterion Covered Total %
statement 25 27 92.5
branch 4 8 50.0
condition 1 3 33.3
subroutine 6 6 100.0
pod 0 2 0.0
total 36 46 78.2


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2             #
3             # Reflector.pm
4             #
5             # Copyright (c) 2002 Ambriel Consulting
6             # sjb Sun Mar 17 20:43:56 GMT 2002
7             #
8              
9             package Crypt::OOEnigma::Reflector ;
10             $VERSION="0.3";
11             =head1 NAME
12              
13             Crypt::OOEnigma::Reflector - The Reflector object for use in Crypt::OOEnigma
14              
15             =head1 SYNOPSIS
16              
17             my $reflector = Crypt::OOEnigma::Reflector->new();
18              
19             # OR
20              
21             my $subHash ={ # A self-inverse cipher with no short-circuits
22             A => "Z",
23             B => "G",
24             # etc
25             };
26             my $reflector = Crypt::OOEnigma::Reflector->new(cipher => $subHash);
27              
28             # for internal use by Enigma machines
29             my $reflected_letter = $reflector->reflect($some_letter);
30              
31             =head1 DESCRIPTION
32              
33             This is the Reflector for use in Crypt::OOEnigmas. Use it when you want to
34             create your own Enigmas with specific properties.
35              
36             =head1 NOTES
37              
38             None
39              
40             =head1 BUGS and CAVEATS
41              
42             =head2 Enigma is weak!
43              
44             Cryptographers talk of the strength of a cryptographic algorithm in term of
45             whether it is computationally feasible to break it. It is, of course,
46             computationally feasible to break an Enigma cipher so don't use it for anything
47             serious!
48              
49             =head1 HISTORY
50              
51             This package was created in spring 2002 as an exercise in OO Perl and preparing
52             modules properly for CPAN. More importantly, the Enigma is interesting.
53              
54             CPAN already has a Crypt::Enigma which is not object oriented and implements
55             only one Enigma (whereas you can create any Enigma-like machine with these
56             objects). Hence the package name Crypt::OOEnigma
57              
58             =head1 SEE ALSO
59              
60             The Pleasures of Counting, T W Korner, CUP 1996. A great book for anyone with
61             the slightest interest in mathematics:
62             ISBN 0 521 56087 X hardback
63             ISBN 0 521 56823 4 paperback
64              
65             The Enigmas:
66             Crypt::OOEnigma::Military
67             Crypt::OOEnigma::Commercial
68              
69             The components:
70             Crypt::OOEnigma::Rotor
71             Crypt::OOEnigma::Reflector
72             Crypt::OOEnigma::Plugboard
73              
74             =head1 AUTHOR
75              
76             S J Baker, Ambriel Consulting, http://ambrielconsulting.com
77              
78             =head1 COPYRIGHT
79              
80             This package is licenced under the same terms as Perl itself.
81              
82             =cut
83 5     5   26091 use Storable ;
  5         4013  
  5         254  
84 5     5   25 use Carp ;
  5         29  
  5         582  
85              
86             # The reflector's substitution must be self-inverse
87             my $subst = {
88             A => "Z", B => "Y", C => "X", D => "W", E => "V",
89             F => "U", G => "T", H => "S", I => "R", J => "Q",
90             K => "P", L => "O", M => "N", N => "M", O => "L",
91             P => "K", Q => "J", R => "I", S => "H", T => "G",
92             U => "F", V => "E", W => "D", X => "C", Y => "B",
93             Z => "A"
94             };
95              
96             my %fields = (
97             cipher => $subst,
98             );
99              
100             # use Autoloading for accessors
101 5     5   1005 use subs qw(cipher);
  5         38  
  5         27  
102              
103             sub new {
104 19     19 0 43 my $invocant = shift ;
105 19   33     83 my $class = ref($invocant) || $invocant ;
106 19         69 my $self = { %fields, @_ } ;
107 19         46 bless $self, $class ;
108              
109             # TODO: check the cipher is in fact self-inverse
110              
111 19         99 return $self ;
112             }
113              
114             sub reflect {
115 3522     3522 0 4287 my $self = shift;
116 3522         4158 my $source = shift;
117 3522         10598 return $self->cipher()->{$source};
118             }
119              
120             sub AUTOLOAD {
121 3550     3550   16449 my $self = shift;
122             # only access instance methods not class methods
123 3550 50       11110 croak "$self is not an object" unless(ref($self));
124 3550         4696 my $name = our $AUTOLOAD;
125 3550 50       7634 return if($name =~ /::DESTROY/ );
126 3550         8823 $name =~ s/.*://; # strip fully-qualified portion
127 3550 50       8129 unless (exists $self->{$name} ) {
128 0         0 croak "Can't access `$name' field in object of class $self";
129             }
130 3550 50       5728 if (@_) {
131 0         0 return $self->{$name} = shift;
132             } else {
133 3550         14076 return $self->{$name};
134             }
135             }
136              
137             1;