Search code examples
javastringmethodsrot13

Java- shifting a ROT13 string


I want to shift a ROT13 string by a user-inputted amount. This is the sample output:

Enter your text to encrypt (!!! to quit): abcdefghijklmnopqrstuvwxyz

Enter amount to shift text by: 3

ORIGINAL: abcdefghijklmnopqrstuvwxyz

ENCRYPTED: defghijklmnopqrstuvwxyzabc 

The user MUST provide a shift value between 0 and 26. If the user goes out of this range, the program should force the user to enter a valid value:

Enter your text to encrypt (!!! to quit): the quick brown fox jumped over the lazy dog
Enter amount to shift text by: -3
ERROR! Shift must be non-negative!
Enter amount to shift text by: 33
ERROR! Shift must be no more than 26!
Enter amount to shift text by: 2

Enter your text to encrypt (!!! to quit): !!! Goodbye!

This is my code that I have written:

import java.util.Scanner;

public class Lab08b 
{

public static void main(String[] args)
{
    Scanner sc = new Scanner (System.in);
    String input = getText(sc);
    int shift = getShift(sc);
    if (input.equals("!!!"))
    {
        System.out.println("Goodbye!");
    }

    while (!input.equals("!!!"))
    {
        String encoded = rot13(input);
        shiftMessage(input, shift);
        displayResults(input, encoded);
        input = getText(sc);
        if (input.equals("!!!"))
        {
            System.out.println("Goodbye!");
        }
    }


}
private static int getShift (Scanner inScanner)
{
    System.out.print("Enter amount to shift text by: ");
    int shift = inScanner.nextInt();

    if (shift < 0)
    {
        System.out.println("ERROR! Shift must be non-negative!");
        System.out.print("Enter amount to shift text by: ");
        shift = inScanner.nextInt();
    }
    else if (shift > 26)
    {
        System.out.println("ERROR! Shift must be non-negative!");
        System.out.print("Enter amount to shift text by: ");
        shift = inScanner.nextInt();
    }
    return shift;
}

private static String getText(Scanner inScanner)
{
    System.out.print("Enter your text to encrypt (!!! to quit): ");
    String original = inScanner.nextLine();

    while (original.equals(""))
    {
        System.out.println("ERROR! String must not be empty!");
        System.out.print("Enter your text to encrypt (!!! to quit): ");
        original = inScanner.nextLine();
    }
    return original;
}


private static String rot13(String input)
{
    String str = "";

    for (int i = 0; i < input.length(); i++)
    {
        char ch = input.charAt(i);
        if (ch >= 'A' && ch <= 'Z')
        {
            ch = (char) (ch + 13);
            if (ch > 'Z')
            {
                ch = (char)(ch - 26);
            }
        }
        else if (ch >= 'a' && ch <= 'z')
        {
            ch = (char)(ch + 13);
            if (ch > 'z')
            {
                ch = (char)(ch - 26);
            }
        }
        str = str + ch;
    }
    return str;
}

private static void displayResults(String inText, String encText)
{
    System.out.print("+");
    for (int i = 13 + encText.length(); i > 0; i--)
    {
        System.out.print("-");
    }
    System.out.println("+");

    System.out.println("| ORIGINAL:  " + inText + " |");
    System.out.println("| ENCRYPTED: " + encText + " |");

    System.out.print("+");
    for(int i = 13 + encText.length(); i > 0; i--){
        System.out.print("-");
    }
    System.out.println("+");
}

private static String shiftMessage(String input, int n)
{
    for (int i = 0; i < input.length(); i++)
    {
        input = input.charAt(input.length()- n) + input.substring(0,input.length());
    }
    return input;
}

}

UPDATE: THIS CODE IS HOW I HAVE PROGRESSED. The actual shifting still does not work http://pastebin.com/v2T1fxEj

I have it printing out the ROT13 encryption and everything, I just don't know how to shift it.

also, when I try to add the "Enter amount to shift by" in the main method below String input = getText(sc), I just end up getting this:

Enter your text to encrypt (!!! to quit): ERROR! String must not be empty!
Enter your text to encrypt (!!! to quit): 

I am not supposed to get that


Solution

  • shiftMessage() is like rot13(), only put in n instead of 13:

    private static String shiftMessage(String input, int n) {
        String str = "";
    
        for (int i = 0; i < input.length(); i++)
        {
            char ch = input.charAt(i);
            if (ch >= 'A' && ch <= 'Z')
            {
                ch = (char) (ch + n);
                if (ch > 'Z')
                {
                    ch = (char)(ch - 26);
                }
            }
            else if (ch >= 'a' && ch <= 'z')
            {
                ch = (char)(ch + n);
                if (ch > 'z')
                {
                    ch = (char)(ch - 26);
                }
            }
            str = str + ch;
        }
        return str;
    }
    

    Now when I call shiftMessage() instead of rot13() from main(), I can:

    Enter your text to encrypt (!!! to quit): abcdefghijklmnopqrstuvwxyz
    Enter amount to shift text by: 1
    +---------------------------------------+
    | ORIGINAL:  abcdefghijklmnopqrstuvwxyz |
    | ENCRYPTED: bcdefghijklmnopqrstuvwxyza |
    +---------------------------------------+
    

    Other issues:

    ERROR! String must not be empty!, which you mention, is a classic with Scanner.nextInt(). nextInt() only reads the number, not the newline following it. So when you subsequently do inScanner.nextLine(), it reads the newline and returns an empty string. I believe the solution is to call nextLine() after nextInt() to get rid of the newline.

    Last, you cannot know in advance that the user will only type an incorrect shift amount once. I can do:

    Enter your text to encrypt (!!! to quit): abc
    Enter amount to shift text by: -3
    ERROR! Shift must be non-negative!
    Enter amount to shift text by: -3
    +----------------+
    | ORIGINAL:  abc |
    | ENCRYPTED: ^_` |
    +----------------+