# -*- Cperl -*-
#-----------------------------------------------------------------------
# Copyright (C) 1999-2000 Julian Fondren
#-- A module implementing a simple encryption
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#-----------------------------------------------------------------------
package Crypt::Rot13;
use strict;
use vars '$VERSION';
$VERSION = 'v0.6';
#=======================================================================
# Public Methods
#-----------------------------------------------------------------------
#-- construct the object
sub new {
my ($proto, @data) = @_;
my $class = ref ($proto) || $proto;
my $self = \@data || [];
bless ($self, $class);
return $self;
}
#-----------------------------------------------------------------------
#-- dereference and return the object
sub peek {
my $self = shift;
return @$self;
}
#-----------------------------------------------------------------------
#-- define the object
sub charge {
my $self = shift;
return @$self = @_;
}
#-----------------------------------------------------------------------
#-- rotate every ASCII letter $degree times in every element of the
#-- object.
sub rot13 {
my $self = shift;
my $degree = (@_ > 0) ? shift : 13;
if (($degree % 26) == 13) {
# This is a rot13, which doesn't require a complex formula.
my @rot13;
foreach my $str ($self->peek ()) {
$str =~ tr/a-zA-Z/n-za-mN-ZA-M/;
push (@rot13, $str);
}
return @rot13;
}
elsif (($degree % 26) == 0) {
# What is anything changed zero times? Right.
return $self->peek ();
}
else {
my ($c, @rot13);
line: foreach my $str (@rot13 = $self->peek ()) {
char: foreach my $i (0 .. (length ($str) - 1)) {
if (substr ($str, $i, 1) =~ /[a-zA-Z]/) {
$c = substr ($str, $i, 1);
substr ($str, $i, 1,
(($c eq lc $c)
? chr ((((ord ($c) - ord ('a')) + $degree) % 26)
+ ord ('a'))
: chr ((((ord ($c) - ord ('A')) + $degree) % 26)
+ ord ('A'))));
}
} # char
} # line
return @rot13;
}
}
1;
__END__
=head1 NAME
Crypt::Rot13 v0.6 - a simple, reversible encryption
=head1 SYNOPSIS
use Crypt::Rot13;
my $rot13 = new Crypt::Rot13;
$rot13->charge ("The quick brown fox jumped over the lazy dog.");
print $rot13->rot13 (), "\n";
print $rot13->rot13 (245.333), "\n";
print $rot13->peek (), "\n";
open (F, "/etc/passwd") or die "$!";
$rot13->charge (<F>);
close (F) or die "$!";
print $rot13->rot13 (-13);
while (<STDIN>) {
$rot13->charge ($_);
print $rot13->rot13 ();
}
$rot13->charge ('a' .. 'z');
foreach (0 .. 26) {
print $rot13->rot13 ($_), "\n";
}
=head1 DESCRIPTION
rot13 is a simple encryption in which ASCII letters are rotated 13
places (see below). This module provides an array object with methods
to encrypt its string elements by rotating ASCII letters n places down
the alphabet.
Think of it this way: all of the letters of the alphabet are arranged
in a circle like the numbers of a clock. Also like a clock, you have
a hand pointing at one of the letters: a. Crypt::Rot13 turns the
hand clockwise n times through 'b', 'c', 'd', etc, and back again to
'a', 26 turns later.
Crypt::Rot13 turns this hand for every letter of every string it
contains a given number of times, the default of which is 13, or
exactly half the number of letters in the alphabet.
=head1 PUBLIC METHODS
=over 4
=item * Crypt::Rot13->new (@arguments)
This creates a Crypt::Rot13 object, which is a blessed array
reference. Any arguments given to C<new> define the array, which is
defaultly empty.
=item * Crypt::Rot13->charge (@arguments)
Any arguments given to C<charge> define the array. If no arguments are
passed, the Crypt::Rot13 array will be empty. The arguments can be
non-strings; see the following example.
my $rot13 = Crypt::Rot13->new ({'foo' => 'bar'}, 111);
print $rot13->peek (), "\n", $rot13->rot13 (), "\n";
=item * Crypt::Rot13->peek ()
This dereferences and returns the Crypt::Rot13 object.
=back
(In case you are wondering, the strange method names of C<peek> and
C<charge> are derived from my original conception of Crypt::Rot13 as a
magical device.)
=over 4
=item * Crypt;:Rot13->rot13 ($degree)
Rotates ASCII alphabetical characters of each element of the array
degree times and returns the changed array without altering the
Crypt::Rot13 object. The degree can be negative and a fractional part
is ignored (to be precise, C<chr> and C<%> ignore it).
Degrees effectively equal to 13 are optimized to a C<tr///>.
Degrees effectively equal to 0 are optimized into a C<peek>.
A degree I<$d> is "effectively equal" to 13 if C<$d % 26 == 13>.
=back
=head1 LICENSE
Copyright (C) 1999-2000 Julian Fondren
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
=head1 BUGS
The algorithm of C<rot13> isn't very easy to understand.
=head1 AUTHOR
Julian Fondren
=head1 SEE ALSO
perl(1) rot13(1)