calvin phung February 2016

Caesar Cipher Uppercase and Lowercase Wrap Around

I am having a problem regarding wrapping around the alphabet with my Caesar Cipher Program.

The program works fine with all lowercase letters. Wraps around perfectly and is able to apply positive and negative shifts. When i try to input an uppercase letter, the uppercase letter does not wrap around.

Here is my code:

public static StringBuilder encode(String str, int numShift)
{

    numShift = numShift % 26;

    //assign each character of the string to a position in the character array
    char[] strChars = str.toCharArray();

    for (int i = 0; i < strChars.length; i++)
        {
            //ignore and continue if the character is not within the alphabet
            if((strChars[i] < 'a' || strChars[i] > 'z') && (strChars[i]<'A' || strChars[i] > 'Z')) 
                continue;

            //apply the shift to each character
            strChars[i] += numShift;

            //wrap around if the shift is beyond Z
            **if(strChars[i] > 'z') 
                {
                strChars[i] -= 'z';
                strChars[i] += ('a' - 1);         
                }**

        }

    StringBuilder encodedStr = new StringBuilder();

    encodedStr.append(strChars);

    return encodedStr;


}
public static void init(){
    Scanner scan = new Scanner(System.in);
    System.out.println("Please enter the string that you would like to  encode:");
    String str = scan.nextLine();
    System.out.println("Please enter the number of letters you would like to shift:");
    int strShift = scan.nextInt();
    scan.close();

    StringBuilder result = encode(str, strShift);
    System.out.println(result);
}
public static void main(String[] args)
{
        init();
}

}

Hints would be much appreciated! Of course, I am not asking anyone to do my work for me but some help would be appreciated! Thank you! :)

Edit: here's the if statement that does the wrap around for lowercase lett

Answers


Lajos Arpad February 2016

Let's implement a wrap-around function for a single character. This will be used by the other method. When you separate your tasks and sub-tasks wisely, you will observe that your problem becomes easier to solve. Here I have based my solution on the fact that char variables are represented as numbers, we know the number of letters and we can use that number as a modulo class, to make sure that algebra is aiding us.

private static char wrapChar(char input, int amount) {
    //assume for now that we have an upper-case letter
    char start = 'A';
    //if the assumption is mistaken...
    if (('a' <= input) && (input <= 'z')) {
        //then, if it is lower-case, then use lower-case
        start = 'a';
    } else if (!(('A' <= input) && (input <= 'Z'))) {
        //target is not letter
        return input;
    }
    //Calculate total offset compared to the first letter of the alphabet
    //be it lower or upper
    int offset = ((input - start) + amount) % 26;
    //If offset happens to be negative, then shift a modulo period of 26
    //To get the correct positive offset
    if (offset < 26) {
        offset += 26;
    }
    //Add the final offset to start and convert it to char
    return ((char)(start + offset));
}

Now, instead of

    //apply the shift to each character
    strChars[i] += numShift;

    //wrap around if the shift is beyond Z
    **if(strChars[i] > 'z') 
        {
        strChars[i] -= 'z';
        strChars[i] += ('a' - 1);         
        }**

You need just:

strChars[i] = wrapChar(strChars[i], numShift);

Post Status

Asked in February 2016
Viewed 1,368 times
Voted 12
Answered 1 times

Search




Leave an answer