File Coverage

blib/lib/Text/Shift.pm
Criterion Covered Total %
statement 14 15 93.3
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 19 20 95.0


line stmt bran cond sub pod time code
1             package Text::Shift;
2              
3             # Boilerplate package imports
4 1     1   25692 use 5.008;
  1         4  
  1         41  
5 1     1   5 use strict;
  1         2  
  1         38  
6 1     1   5 use warnings;
  1         7  
  1         43  
7 1     1   6 use Carp;
  1         2  
  1         128  
8              
9             # Implementation-specific imports
10 1     1   889 use Crypt::Cipher v0.02;
  1         8143  
  0            
11             use integer; # potential speed increase
12              
13             # Constants
14             use constant {
15             # Change the following values to modify the default alphabets
16             UPPER => join("","A".."Z"),
17             LOWER => join("","a".."z"),
18             NUMBS => join("",0..9)
19             };
20             use constant { # constant is broken for self-reference
21             FROM => join("",UPPER,LOWER,NUMBS),
22            
23             # THE FOLLOWING THREE CONSTANTS MUST NOT CHANGE
24             UPPDEX => 0,
25             LOWDEX => 1,
26             NUMDEX => 2
27             };
28            
29             # Class variables
30             our @ISA = qw(Crypt::Cipher);
31             our $VERSION = '1.00';
32             our %_abs; # Hash of callers' package names pointing to arrays
33             # The array is made up of UPPERCASE, LOWERCASE, NUMBERS
34              
35              
36             #############
37             # FUNCTIONS #
38             #############
39             # The following function rotates the alphabet by magnitude amount
40             sub _rotate_alphabet($$) {
41             # Get parameters
42             my($string,$mag) = (shift, int(shift));
43             my $strlng = length($string);
44            
45             # Handle outliers
46             $mag += $strlng while($mag < 0); # Negative magnitude
47             $mag %= $strlng if($mag > $strlng); # Too large magnitude
48              
49             # Return rotated string
50             return $string if($mag == 0);
51             $string .= substr($string,0,$mag, "");
52             return $string;
53             }
54              
55             ###########
56             # Methods #
57             ###########
58              
59             # Create the alphabet control methods
60             BEGIN {
61             my $funcref = sub( $ ) {
62             my $index = shift;
63             return sub($$) {
64             (undef, my $caller) = (shift, caller);
65             if(scalar(@_)) {
66             # Modifier return
67             $_abs{$caller} = [] unless($_abs{$caller});
68             return $_abs{$caller}->[$index] = join("",@_);
69             } else {
70             # Accessor return
71             return $_abs{$caller}->[$index];
72             }
73             };
74             };
75            
76             *uppercase = $funcref->(UPPDEX);
77             *lowercase = $funcref->(LOWDEX);
78             *numbers = $funcref->(NUMDEX);
79             }
80              
81             sub new($;$$$) {
82             # get the parameters
83             my $caller = caller;
84             my $class = shift;
85             my $caps = (int(shift) or 0);
86             my $small = @_ ? int(shift) : $caps;
87             my $nums = @_ ? int(shift) : $caps;
88            
89            
90             # Get the cipher mapping -- note order in source
91             if($_abs{$caller}) {
92             our @source;
93             *source = $_abs{$caller};
94             my $upcase = ($source[UPPDEX] or UPPER);
95             my $lwcase = ($source[LOWDEX] or LOWER);
96             my $numbrs = ($source[NUMDEX] or NUMBS);
97             my $to =
98             _rotate_alphabet($upcase, $caps).
99             _rotate_alphabet($lwcase, $small).
100             _rotate_alphabet($numbrs, $nums);
101             return $class->SUPER::new(
102             ($upcase.$lwcase.$numbrs),
103             $to
104             );
105             } else {
106             my $to =
107             _rotate_alphabet(UPPER, $caps).
108             _rotate_alphabet(LOWER, $small).
109             _rotate_alphabet(NUMBS, $nums);
110             return $class->SUPER::new(FROM,$to);
111             }
112             }
113              
114              
115             return 1;
116             __END__