#!/usr/bin/perl # # rot13 This script is a rudimentary letter-substitution code. It # replaces each letter with the letter that follows 13 letters # later in the alphabet, with the count wrapping from the end # to the beginning. For example, 'a' is replaced with 'm', # 'b' with 'n', 'p' with 'c', etc. # # The command is used in this way: # # rot13 [-replace | -help | -Version] # # Revision History # 1.0 Initial revision. 130606 # 1.1 Added -numrot. 130707 # 1.2 Added licensing info. 180531 # # Written by Wayne Morrison, 130606. # # Copyright 2013 Wayne Morrison # # Licensed 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. # use strict; use Getopt::Long qw(:config no_ignore_case_always); # # Version information. # my $NAME = "rot13"; my $VERS = "$NAME version: 1.2"; ############################################################################ # # Options fields. # my %opts = (); # Options. # # Command line arguments. # my @opts = ( 'numrot', # Rotate numbers. 'replace', # Replace file contents in place. 'help', # Give a help message. 'Version', # Display the program version. ); my $numrot = 0; my $repflag = 0; ############################################################################ main(); exit(0); #----------------------------------------------------------------------------- # Routine: main() # sub main { $| = 1; # # Munch on the options and arguments. # optsandargs(); # # If no argument was given, we'll translate stdin. # If arguments were given, we'll translate those files. # if(@ARGV == 0) { # # Translate stdin. # transstdin(); } else { # # Translate each file. # foreach my $fn (@ARGV) { transfile($fn); } } } #---------------------------------------------------------------------- # Routine: optsandargs() # # Purpose: Parse the command line for options and arguments. # sub optsandargs { # # Parse the options. # GetOptions(\%opts,@opts) || usage(); # # Check for some immediate-action options. # usage() if(defined($opts{'help'})); version() if(defined($opts{'Version'})); $repflag = $opts{'replace'}; $numrot = $opts{'numrot'}; # # Ensure -replace is only given with arguments. # if($repflag && (@ARGV == 0)) { print STDERR "-replace must be used with files\n"; exit(1); } } #---------------------------------------------------------------------- # Routine: transstdin() # # Purpose: Read and translate data from standard input. # sub transstdin { while(<>) { tr/A-Za-z/N-ZA-Mn-za-m/; tr/0-9/9876543210/ if($numrot); print; } } #---------------------------------------------------------------------- # Routine: transfile() # # Purpose: Read and translate data from a file. If the user gave the # -replace option, the translated file will be rewritten. # Otherwise, the translated file will be written to stdout. # sub transfile { my $fn = shift; # File to translate. my $fbuf = ''; # File buffer. # # Open the file. # if(open(FN, "< $fn") == 0) { print STDERR "unable to open \"$fn\"\n"; return; } # # Translate the file and save it in a buffer. # while() { tr/A-Za-z/N-ZA-Mn-za-m/; tr/0-9/9876543210/ if($numrot); $fbuf .= $_; } close(FN); # # Write the translated file. # If the user wants the file rewritten, we'll do that. # Otherwise, we'll write the translated file to stdout. # if($repflag) { if(open(FN, "> $fn") == 0) { print STDERR "unable to open \"$fn\" for writing\n"; return; } print FN $fbuf; close(FN); } else { print $fbuf; } } #---------------------------------------------------------------------- # Routine: version() # # Purpose: Print the version number(s) and exit. # sub version { print STDERR "$VERS\n"; exit(0); } #---------------------------------------------------------------------- # Routine: usage() # # Purpose: Give usage message and exit. # sub usage { print STDERR "usage: rot13 [options] \n"; print STDERR "\n"; print STDERR "\twhere [options] are:\n"; print STDERR "\t\t-numrot\n"; print STDERR "\t\t-replace\n"; print STDERR "\t\t-help\n"; print STDERR "\t\t-Version\n"; exit(0); } 1; ############################################################################## =pod =head1 NAME B - compare checksums of two groups of files =head1 SYNOPSIS rot13 [options] =head1 DESCRIPTION B is a rudimentary letter substitution code. It replaces each letter with the letter that follows 13 letters later in the alphabet, with the count wrapping from the end to the beginning. For example, 'a' is replaced with 'm', 'b' with 'n', 'p' with 'c', etc. Due to the nature of this code, the same program can be used to encode and decode a block of text. By default, only alphabetic characters are rotated. The I<-numrot> option will also rotate numbers. If no files are given on the command line, text on standard input will be translated. Output is usually written to standard output, but if the I<-replace> option and a set of files are given, then the files will be translated in place. This is a I well-known cipher and shouldn't be used for anything that must be kept secret. These days, it is often used for hiding spoilers in public postings. That's about the extent of what it should be trusted for. A similar such program used to be standard, but it seems to have disappeared. =head1 OPTIONS B takes the following options: =over 4 =item I<-numrot> If this option is given, numbers will also be rotated. Despite the program's name, a 10-place rotation will be performed. 0 is replaced with 5, 1 with 6, etc. =item I<-replace> If this option is given, the specified files will be translated in place. This may only be used with a set of files and may not be used with input coming from standard input. =item I<-Version> Display the version information for B. =item I<-help> Display a help message. =back =head1 AUTHOR Wayne Morrison, wayne@waynemorrison.com =head1 LICENSE Copyright 2013 Wayne Morrison Licensed 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. =head1 SEE ALSO B =cut