#!/usr/bin/perl -w # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ######################################################################## # penihip - Generate new words using a caesar cipher. # # Notes: # - Does not attempt to handle sentence structure, grammar, etc. # # FIXME: Large negative offsets will probably break. # ######################################################################## use Getopt::Std; use strict; # Get the options my %options = (); getopts('deo:vh', \%options) || &Usage(); my $mode = ""; my $offset = "1"; OPT_CASE: { if ($options{e}) { $mode="e"; last OPT_CASE; } if ($options{d}) { $mode="d"; last OPT_CASE; } &Usage; } if ($options{o}) { if ($options{o} =~ /^[+-]?\d+$/) # an integer { $offset = $options{o}; } else { &Usage; } } if ($options{h}) { &Usage; } # Initialise my @consonants = ('b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'); my @vowels = ('a','e','i','o','u'); while (my @inputLines = ) { foreach my $line (@inputLines) { my @characters = split(//, $line); foreach my $character (@characters) { my ($type, $position) = CharacterPosition(lc($character)); if ($options{v}) { print STDERR "character=$character type=$type position=$position "; } my $newCharacter = $character; if ($position > -1) { $newCharacter = GetNewCharacter($type, $position); if ($character =~ /[A-Z]/) { $newCharacter =~ tr/[a-z]/[A-Z]/; } } print $newCharacter; if ($options{v}) { print STDERR "newCharacter=$newCharacter\n"; } } } } # CharacterPosition($character) # Lookup a single character and determine its "type" and its position in # the list. sub CharacterPosition { my ($c) = @_; my $type = ""; my $position = -1; my $i; CHARACTERS: { CONSONANTS: foreach $i (0..$#consonants) { if ($consonants[$i] eq "$c") { $type = "consonant"; $position = $i; last CHARACTERS; } } VOWELS: foreach $i (0..$#vowels) { if ($vowels[$i] eq "$c") { $type = "vowel"; $position = $i; last CHARACTERS; } } } return($type, $position); } # GetNewCharacter($type, $position) # Calculate a new position based on $offset and $mode # and return the character at that position in the relevant list. sub GetNewCharacter { my ($type, $position) = @_; my $newCharacter = ""; my $newPosition = $position; if ($mode eq "e") { $newPosition += $offset; } else { $newPosition -= $offset; } CHARACTER_CASE: { if ($type eq "consonant") { while ($newPosition > $#consonants) { $newPosition -= $#consonants + 1; } $newCharacter = $consonants[$newPosition]; last CHARACTER_CASE; } if ($type eq "vowel") { while ($newPosition > $#vowels) { $newPosition -= $#vowels + 1; } $newCharacter = $vowels[$newPosition]; last CHARACTER_CASE; } } if ($options{v}) { print STDERR "newPosition=$newPosition "; } return($newCharacter); } # Usage() # Show the usage and then exit. sub Usage { print STDERR qq!Usage: $0 -e [-o integer] [-v] [-h] < infile > outfile # encipher $0 -d [-o integer] [-v] [-h] < infile > outfile # decipher where: -e = encipher, shift by offset to the right -d = decipher, shift by offset to the left -o integer = offset by integer number of characters, default=1 -v = be verbose -h = help !; exit(1); }