Preparation

a. Make sure you are booted into the Mac OSX side of the computer.

b. Mount the COURSES network drive by double clicking the alias icon you created previously. If you were unable to set up the alias, you can follow the Course Directory Setup instructions to mount the drive and create the alias.

c. Open up a Terminal, navigate to your StuWork directory, create a folder named lab-09-19, and change your directory to the newly created folder. (Remember that you should replace USERNAME with your actual username!)

$ cd /Volumes/COURSES/cs201-01-f18/StuWork/USERNAME/
$ mkdir lab-09-19
$ cd lab-09-19

d. Discuss with your partner what text editor you would like to use and open it up. Don’t be afraid to learn something new! You might find that you really like it! (I will be using Brackets primarily when writing live code.)

Goal

The goal of this lab is to get you more hands-on experience with the concepts we are learning in class. In particular, we will create a Caesar cipher which is a simple way to encrypt and decrypt text using a secret number called a shift. To encrypt a message, what you do is replace every character in your message with one that is shift number of characters ahead in the alphabet. For example, if shift=3, then all characters in the alphabet would be shifted by three and those on the end will “wrap around” to the beginning.

Alphabet A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Alphabet Shifted by 3 D E F G H I J K L M N O P Q R S T U V W X Y Z A B C

Using a shift of 3, a message like “hello” would be encrypted to “khoor” since the character “h” gets shifted to “k” (since “k” is three characters ahead of “h”) and so on.

Exercise 1

Since there are a variety of ways to encrypt and decrypt messages, we will first create a general interface for our Caesar cipher.

a. Create a new file Encrypter.java that contains the following code.

public interface Encrypter
{
    public String encrypt(String message);
    public String decrypt(String secretMessage);
}

b. Create a new file CaesarCipher.java that contains the following starter code.

public class CaesarCipher implements Encrypter
{
    @Override
    public String encrypt(String message)
    {
        return null;   // stub to make the code compile
    }

    @Override
    public String decrypt(String secretMessage)
    {
        return null; // stub to make the code compile
    }
}

c. Make sure the code compiles. You can do this via the Terminal if you are in the same directory and execute the following.

$ javac *.java

Exercise 2

Since every Caesar cipher needs an integer shift value, we need to add that information to our class.

a. Create a private instance variable shift of type int.

b. Create a constructor that takes in a single parameter shift and stores it in the instance variable.

c. Create a default constructor that defaults to shift=13 since it is a common shift value. Use the this(..) syntax to call the other constructor here.

Exercise 3

We will start by learning to encrypt a single character.

a. Add a private method to your CaesarCipher with the following signature

private char shiftChar(char letter, int amount)

b. Implement the method so that it does the following:

  • If letter is a lowercase or uppercase character, the method returns a new char that is amount number of characters ahead in the alphabet. It should also maintain its case (uppercase stay uppercase, and lowercase stay lowercase)
  • If letter is not alphabetic, it returns letter (i.e. it does not change its value)

Below is a table that shows what the output should be for various inputs.

Input 1: letter Input 2: amount Output
a 3 d
z 1 a
b -1 a
h 5 m
A 3 D
Z 3 C

If you are struggling with this part, ask your instructor or prefect.

c. Test your method by creating a main method in your CaesarCipher file that shifts various characters and prints their values to see it is working properly.

Exercise 4

Now we are ready to implement the encrypt and decrypt methods!

a. Implement the encrypt method by looping over all the characters of the message and calling your shiftChar method to shift it by one. Since you are constructing a new string from individual characters, you might consider using the StringBuilder class for this purpose.

Hint: to loop over the characters of the string, you can use the following loop structure.

String str = "Hello";
for (int i = 0; i < str.length(); i++)
{
    char curChar = str.charAt(i);
    System.out.println(curChar);
}

b. Implement the decrypt method by shifting characters in the opposite direction in the same way as in part a.

c. Are your implementations of encrypt and decrypt basically the same? Duplicating code like this is bad practice! Create a private helper method with the following signature that shifts an entire string by an integer amount.

private String shiftString(String str, int amount)

Now change your encrypt and decrypt methods so that they simply call the shiftString method instead.

Exercise 5

Since we are done implementing the CaesarCipher class, we should test our encryption and decryption methods!

a. Create a main method in the CaesarCipher class if there isn’t one there already.

b. Create several CaesarCipher objects with various shift values and try encrypting a variety of phrases and then decrypting them. Print off the intermediate steps so you can see their results before and afterwards.

Before You Leave

Get in the habit of emailing the code written during class to your partner. Since only one account is being used at a time, the files created will only be accessible from the user that is logged in. Later in the course, having these in-class files will be essential for reviewing and studying!

Additional Exercises

Many of you have requested I give additional exercises to practice using Java. Here are a few that I think will help you out.

Practice Problem 1

Write a method that takes an array of integers as a parameter and reverses the array in place. Below is what the method signature should be.

void reverseArray(int[] arr)

Practice Problem 2

Write a method that takes an array of integers and returns the largest integer in that array.

Practice Problem 3

Write a method that takes an array of integers arr and an integer value and creates a new array that has the same values as the original except that all occurrences of value are removed. Below is the signature for the method.

int[] removeAll(int[], int value)

Hint: you will need to iterate over the array twice. Once to find how many times value occurs so that you know how large to create the new array, and then again to copy all the values.

Practice Problem 4

Write a method that takes a positive integer n as input and prints the first n Fibonacci numbers.