Lab #8: Cyclic Shifting of Alphabets

The goal of this lab is to write a class CharacterShift that reads lines from a specified file and writes the lines to a specified file while making a specified number of cyclic shift on each numeral, on each lower-case letter, and on each upper-case letter.

At the start, the program receives from the user:

  1. the name of the input file (String),
  2. the name of the output file (String), and
  3. the amount of shift as a positive integer (int)

During the process of receiving these pieces of information, the program performs the following tests:

  1. The program tests whether the specified input file exists, which is a must for the program to run. If the file does not exist, the program throws a new IllegalArgumentException with which to inform the error and quits. The test can be performed by creating a new File object using the input file name as the parameter and then executing the exists() on the file object.
  2. The program tests whether the specified output file is to have a different path than the specified input file. This can be performed by:
    1. creating a new File object using the output file name as the parameter,
    2. saving the paths returned by the method getAbsollutePath() on the input File object (which wa created in Test 1) and on the output File object to two String variables, and then
    3. executing method comparison on the two String variables using the compareTo() (be mindful of the syntax) If the paths happen to be the same, the program throws a new IllegalArgumentException with which to inform the error and quits.
  3. The program tests whether the specified shift amount is a positive integer. If the test fails, the program throws a new IllegalArgumentException with which to inform the error and quits.

Once these tests have passed, the program opens the input file using a new Scanner object (with the input File object in the above as the parameter) and opens the output file using a new PrintStream object (with the output File object in the above as the parameter).

The program then performs the conversion. The conversion goes as follows:

The shifting will be performed in the following cyclic manner:

Let diff be the shift amount that the user has specified at the beginning of the program. The value of diff is a positive integer.

Given a String inLine the conversion goes as follows:

LowerCase Letter
The lower-case letters ‘a’ - ‘z’ can be represented using the numbers 0 - 25 by considering their distance from the first letter ‘a’. In other words, we identify 0 as ‘a’ 1 as ‘b’, and so on. Given a lower-case letter, say myChar, this representative number can be obtained by expression

myChar - ‘a’'

By shifting a lower-case letter c by 1 we mean switching from the lower-case letter c to the next letter in the lower-case leter group, e.g., from ‘b’ to ‘c&squo; and from ‘x’ to ‘y’. Since ‘z’ is the last letter of the alphabet, we circle back to the first letter of the alphabet and treat ‘a’ as the next letter of ‘’.

Now, given a positive integer k, by

shifting myChar by k

we mean to perform this one-letter shift to myChar successively k times. It is easy to observe that, since there are 26 letters in the lower-case letter group, 26 shifts take each letter back to the original. Thus, given any positive integer k, shifting myChar by k is equivalent to:

shifting myChar by (k % 26).

Furthermore, since myChar is the result of shifting ‘a’ by (myChar - ‘a’) we have that shifting myChar by k is equivalent to:

shifting ‘a’ myChar by ( mychar - ‘a’ + k ) % 26

Given a char myChar, which is a lower-case alphabet, we can obtain the letter as the result of performing shifting myChar by k by the expression

(char)( ‘a’ + ( myChar - ‘a’ + k ) % 26 )

Our goal is to each occurrence of a lower-case letter in the lines of the input file using this formula.

Upper-case Letter
The treatment of an upper-case letter is much the same as the lower-case letter, expected that ‘A’ replaces the ‘a’ in all the expression, that is, we use the expression

(char)( ‘A’ + ( myChar - ‘A’ + k ) % 26 )

You can write a public static method by the name of convert that takes two parameters, a char by the name of myChar and an int by the name of k, and returns the char as defined in the above, in the case where myChar is a lower-case letter (the case can be tested using the method call Character.isLowerCase( myChar )) or the case where myChar is an upper-case letter (the case can be tested using the method call Character.isUpperCase( myChar )), and returns myChar, otherwise.

Now given a line on which to make the conversion on all the alphabet letters, we can think of creating a new String as follows:

You may use the template CharacterShift.java.

Below is an example of executing the code that satisifed the requirement. In the example, the first three runs fail Test 1, Test 2, and Test 3 in this order by supplying the name of a non-existing file as the input file, by supplying the same name for the input and the output, and by supplying a negative number for the shift amount, respectively. The fourth time the program completes. The contents are shown using cat command.


% java CharacterShift
Enter input file name: foo.txt
Exception in thread "main" java.lang.IllegalArgumentException: The file does not exist!
at CharacterShift.main(CharacterShift.java:25)

% java CharacterShift
Enter input file name: shiftIn.txt
Enter output file name: shiftIn.txt
Exception in thread "main" java.lang.IllegalArgumentException: The file names are identical!
at CharacterShift.main(CharacterShift.java:34)

% java CharacterShift
Enter input file name: shiftIn.txt
Enter output file name: shiftOut.txt
Enter positive shift amount:-100
Exception in thread "main" java.lang.IllegalArgumentException: The number is not positive!
at CharacterShift.main(CharacterShift.java:41)

% java CharacterShift
Enter input file name: shiftIn.txt
Enter output file name: shiftOut.txt
Enter positive shift amount:10

% cat shiftIn.txt
The goal of this lab is to write a class CharacterShift that reads
lines from a specified file and writes the lines to a specified file
while making a specified number of cyclic shift on each numeral, on
each lower-case letter, and on each upper-case letter.

At the start, the program receives from the user:

(a) the name of the input file (String),
(b) the name of the output file (String), and
(c) the amount of shift as a positive integer (int)

% cat shiftOut.txt
Dro qykv yp drsc vkl sc dy gbsdo k mvkcc MrkbkmdobCrspd drkd boknc
vsxoc pbyw k czomspson psvo kxn gbsdoc dro vsxoc dy k czomspson psvo
grsvo wkusxq k czomspson xewlob yp mimvsm crspd yx okmr xewobkv, yx
okmr vygob-mkco voddob, kxn yx okmr ezzob-mkco voddob.

Kd dro cdkbd, dro zbyqbkw bomosfoc pbyw dro ecob:

(k) dro xkwo yp dro sxzed psvo (Cdbsxq),
(l) dro xkwo yp dro yedzed psvo (Cdbsxq), kxn
(m) dro kwyexd yp crspd kc k zycsdsfo sxdoqob (sxd)

Go back to the lab main page

Go back to the home page