Crypt::OOEnigma::Military - A military Enigma machine circa 1940. It


Crypt-OOEnigma documentation Contained in the Crypt-OOEnigma distribution.

Index


Code Index:

NAME

Top

Crypt::OOEnigma::Military - A military Enigma machine circa 1940. It differs from the Commercial Enigma in the addition of a plugboard before the rotors.

SYNOPSIS

Top

  use Crypt::OOEnigma::Military;
  # An Enigma with 3 default Rotors (with identity substitutions)
  my $enigma = new Crypt::OOEnigma::Military;

  # OR
  use Crypt::OOEnigma::Military;
  use Crypt::OOEnigma::Rotor;
  my @rotors = ()
  # Populate the list of Crypt::OOEnigma::Rotor
  Crypt::OOEnigma::Military->new( rotors => [@rotors] );

  # OR EVEN

  use Crypt::OOEnigma::Military;
  use Crypt::OOEnigma::Rotor;
  use Crypt::OOEnigma::Reflector;
  use Crypt::OOEnigma::Plugboard;
  my @rotors = ()
  # Populate the list of Crypt::OOEnigma::Rotor, see relevant pod
  my $reflector = new Crypt:OOEnigma::Reflector(params); # see relevant pod
  my $plugboard = new Crypt:OOEnigma::Plugboard(params); # see relevant pod
  Crypt::OOEnigma::Military->new( rotors => [@rotors],
                                  plugboard => $plugboard,
                                  reflector => $reflector);

  my $cipher = $enigma->encipher($mesg);
  my $decode = $enigma->encipher($cipher); # self-inverse

  # for internal use

  $enigma->init(); # returns the rotors to their initial state

DESCRIPTION

Top

This module provides a Military Enigma machine which differs in that a Plugboard is added before the Rotors.

You should usually create a Military Enigma with your own Plugboard, Rotors and Reflector.

NOTES

Top

None

BUGS and CAVEATS

Top

Enigma is weak!

Cryptographers talk of the strength of a cryptographic algorithm in term of whether it is computationally feasible to break it. It is, of course, computationally feasible to break an Enigma cipher so don't use it for anything serious!

HISTORY

Top

This package was created in spring 2002 as an exercise in OO Perl and preparing modules properly for CPAN. More importantly, the Enigma is interesting.

CPAN already has a Crypt::Enigma which is not object oriented and implements only one Enigma (whereas you can create any Enigma-like machine with these objects). Hence the package name Crypt::OOEnigma

SEE ALSO

Top

The Pleasures of Counting, T W Korner, CUP 1996. A great book for anyone with the slightest interest in mathematics ISBN 0 521 56087 X hardback ISBN 0 521 56823 4 paperback

Crypt::OOEnigma::Military

The components: Crypt::OOEnigma::Rotor Crypt::OOEnigma::Reflector Crypt::OOEnigma::Plugboard

AUTHOR

Top

S J Baker, Ambriel Consulting, http://ambrielconsulting.com

COPYRIGHT

Top


Crypt-OOEnigma documentation Contained in the Crypt-OOEnigma distribution.

#!/usr/bin/perl -w
#
# Military.pm
#
# Copyright (c) 2002 Ambriel Consulting
# sjb Mon Mar 18 20:55:53 GMT 2002
#

package Crypt::OOEnigma::Military ;
$VERSION="0.3";
use Carp ;
use Crypt::OOEnigma::Rotor ;
use Crypt::OOEnigma::Reflector ;
use Crypt::OOEnigma::Plugboard ;


# use Autoloading for accessors
use subs qw( rotors reflector plugboard  );

my %fields = (
  rotors          => undef,
  reflector       => undef,
  plugboard       => undef
);

sub new {
  my $invocant = shift ;
  my $class = ref($invocant) || $invocant ;
  my $self = { %fields, @_ } ; 
  bless $self, $class ;
  
  # only set valid rotors
  if( defined($self->rotors())){
    foreach my $r (@{$self->rotors()}){
      if(keys(%{$r->cipher()}) == 26){
        # This rotor is ok
      } else {
        croak("An invalid rotor was provided.");
      }
    }
  } else {
    # use three default rotors
    my $r1 = Crypt::OOEnigma::Rotor->new();
    my $r2 = Crypt::OOEnigma::Rotor->new();
    my $r3 = Crypt::OOEnigma::Rotor->new();
    $self->rotors([$r1, $r2, $r3]);
  }
  
  # only set a valid plugboard
  if( defined($self->plugboard()) ){
    if(keys(%{$self->plugboard()->cipher()}) == 26){
      # This plugboard is ok TODO: improve checking - self-inverse?
    } else {
      croak("An invalid plugboard was provided.");
    }
  } else {
    $self->plugboard(Crypt::OOEnigma::Plugboard->new());
  }
  
  # Reflector does not require setup
  $self->reflector(Crypt::OOEnigma::Reflector->new());
  
  $self->init();
  return $self ;
}

sub init {
  my $self = shift ; 
  # Initialise all the rotors
  foreach my $r (@{$self->rotors()}){
    $r->init();
  }
  # Plugboard and reflector require no initialisation
}


sub encipher {
  my $self = shift;
  my $work = shift ;
  $work    =~ s/\s/X/g;
  $work    = uc($work);
  my $result = "";
  my @rotors = @{$self->rotors()};

  foreach my $ch ( split //, $work ){
    # pass through plugboard
    $ch = $self->plugboard()->encode($ch);
    # encipher in every rotor
    foreach $r (@rotors){
      $ch = $r->encode($ch);
    }
    # reflect
    $ch = $self->reflector()->reflect($ch);
    # reverse encipher in every rotor
    foreach $r (reverse @rotors){
      $ch = $r->revencode($ch);
    }
    # nudge all the rotors
    foreach $r (@rotors){
      $r->next();
    }
    # pass through plugboard - self-inverse
    $ch = $self->plugboard()->encode($ch);
    $result .= $ch ;
  }

  $self->init();
  return $result;
}

sub AUTOLOAD {
  my $self = shift;
  # only access instance methods not class methods
  croak "$self is not an object" unless(ref($self));
  my $name = our $AUTOLOAD;
  return if($name =~ /::DESTROY/ );
  $name =~ s/.*://;   # strip fully-qualified portion
  unless (exists $self->{$name} ) {
    croak "Can't access `$name' field in object of class $self";
  } 
  if (@_) {
    return $self->{$name} = shift;
  } else {
    return $self->{$name};
  } 
}

1;