From 24dedb2618abc80efc2af10de597d1debbeba69f Mon Sep 17 00:00:00 2001 From: dakkar Date: Mon, 29 Aug 2011 14:49:07 +0100 Subject: crypto train, with some stepping --- lib/Enigmatic/CryptTrain.pm | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 lib/Enigmatic/CryptTrain.pm (limited to 'lib/Enigmatic/CryptTrain.pm') diff --git a/lib/Enigmatic/CryptTrain.pm b/lib/Enigmatic/CryptTrain.pm new file mode 100644 index 0000000..06a11d2 --- /dev/null +++ b/lib/Enigmatic/CryptTrain.pm @@ -0,0 +1,86 @@ +package Enigmatic::CryptTrain; +use DAKKAR::p 'class'; +use Enigmatic::Types qw(Letter RotorPos); +use MooseX::Types::Moose qw(ArrayRef); +use Moose::Util::TypeConstraints; + +has rotors => ( + isa => ArrayRef[class_type('Enigmatic::Rotor')], + traits => ['Array'], + writer => 'set_rotors', + handles => { + set_rotor => 'set', + rotor_at => 'get', + rotors => 'elements', + }, +); + +sub rotor_count { + my ($self) = @_; + + return scalar $self->rotors; +} + +has reflector => ( + isa => class_type('Enigmatic::Reflector'), + writer => 'set_reflector', + reader => 'reflector', +); + +has positions => ( + isa => ArrayRef[RotorPos], + traits => ['Array'], + writer => 'set_positions', + handles => { + set_position => 'set', + position_at => 'get', + positions => 'elements', + }, +); + +sub map { + my $self = shift; + my ($letter) = pos_validated_list( + \@_, + { isa => Letter }, + ); + + for my $element ( + $self->rotors, + $self->reflector, + (reverse $self->rotors), + ) { + $letter = $element->map($letter); + } + $self->step_positions(); + + return $letter; +} + +sub _inc_position { + my ($self,$idx) = @_; + + my $cur = $self->position_at($idx); + $cur = ($cur+1)%26; + $self->set_position($idx,$cur); + return $cur; +} + +sub rotor_window_at { + my ($self,$idx) = @_; + + return ['A'..'Z']->[$self->position_at($idx)] +} + +sub step_positions { + my ($self) = @_; + + for my $pos (0 .. $self->rotor_count -1) { + $self->_inc_position($pos); + my $rot = $self->rotor_at($pos); + last + unless $rot->has_notch_at($self->rotor_window_at($pos)); + } + + return; +} -- cgit v1.2.3