Challenges with caesar-cipher: Encoding and Decoding code

1.5k views Asked by At

I am new to Java and this is what I have to do:
Write a program that lets the user input a message and a shift value and then outputs the encoded message
Write a separate program that lets the user input a coded message using the first program and then decodes it for you and you cannot use StringBuffer or StringBuilder

What I am trying to do here is make the second part of the program but I am having some problems. When you add shift value, it only encodes it by 1 no matter what number you input and when I try to decode, it gives me an error.

public class part2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String text;
        String key;
        int shift;

        System.out.println("Enter message:");
        text = sc.nextLine();
        System.out.println("Enter encryption key:");
        key = sc.next();
        shift = key.length(); {
            System.out.println("1.Encrypt\n2.Decrypt\n3.Exit...");
            int choice = sc.nextInt();
            switch (choice) {
                case 1:
                    System.out.println("Encryptedmessage..." + encrypt(text, shift));
                    break;
                case 2:
                    //send retrived string from encrypt() method and keyLength to decrypt() method it returns 'Decrypted' string
                    System.out.println("Decrypted message..." + decrypt(encrypt(text, shift), shift));
                    break;
                case 3:
                    //exit from the program
                    System.exit(0);
                    break;
                default:
                    System.out.println("Invalid option..");
            }
        }
    }
    public static String encrypt(String text, int shift) {

        for (int i = 0; i < text.length(); i++) {
            char letter = text.charAt(i);

            // shift only letters (leave other characters alone)
            if (letter >= 'a' && letter <= 'z') {
                letter = (char)(letter + shift);

                // may need to wrap around
                if (letter > 'z') {
                    letter = (char)(letter - 26);
                } else if (letter < 'a') {
                    letter = (char)(letter + 26);
                }
            }
            System.out.print(letter);
        }
        return null;
    }

    public static String decrypt(String str, int keyLength) {
        String decrypted = "";
        for (int i = 0; i < str.length(); i++) {

            int c = str.charAt(i);

            if (Character.isUpperCase(c)) {
                c = c - (keyLength % 26);
                if (c < 'A')
                    c = c + 26;
            } else if (Character.isLowerCase(c)) {
                c = c - (keyLength % 26);
                if (c < 'a')
                    c = c + 26;
            }
            decrypted = decrypted + (char) c;
        }
        return decrypted;
    }
}

This is my code for the first part:

public static void main(String[] args) {

        Scanner console = new Scanner(System.in);
        System.out.print("Type a message you want to be coded: ");
        String message = console.nextLine();
        message = message.toLowerCase();

        System.out.print("Enter a Shift: ");
        int key = console.nextInt();
    if (key < 1 || key > 25) {
                System.out.printf(" The key must be between 1 and 25, you entered %d.\n", key);
            }
        while (key < 1 || key > 25);

        encode(message, key);
    }

    // This method encodes the given text string using a Caesar
    // cipher, shifting each letter by the given number of places.
    public static void encode(String text, int shift) {
        System.out.print("The encoded message: \n");
        for (int i = 0; i < text.length(); i++) {
            char letter = text.charAt(i);

            // shift only letters (leave other characters alone)
            if (letter >= 'a' && letter <= 'z') {
                letter = (char) (letter + shift);

                // may need to wrap around
                if (letter > 'z') {
                    letter = (char) (letter - 26);
                } else if (letter < 'a') {
                    letter = (char) (letter + 26);
                }
            }
            System.out.print(letter);
        }
    }

This is the code for first part and it works perfectly. Just need help with the second part

1

There are 1 answers

4
Cory Owens On

You have a couple of problems here.

First, you are not quite done with the first part, like you think. Let's look at your encrypt method:

public static String encrypt(String text, int shift) {

    for (int i = 0; i < text.length(); i++) {
        char letter = text.charAt(i);

        // shift only letters (leave other characters alone)
        if (letter >= 'a' && letter <= 'z') {
            letter = (char)(letter + shift);

            // may need to wrap around
            if (letter > 'z') {
                letter = (char)(letter - 26);
            } else if (letter < 'a') {
                letter = (char)(letter + 26);
            }
        }
        System.out.print(letter); // <- This is part of your problem
    }
    return null; // <- This is part of your problem
}

When we call this, we output the encoded string to the console, but look at the last line: we return null. You need to figure out a way to store the encoded message and then return it. Otherwise, you will always get a NullPointerException on this line in your main method:

System.out.println("Decrypted message..." + decrypt(encrypt(text, shift), shift));

The second problem is that you may be misunderstanding your assignment. Looking at that line above, once you have encrypt working, you still have a useless decrypt option: it will always give you back the message you enter. What I think you want to be doing is to just decrypt the message, with the user passing in an already encrypted message. But, that's just my hunch, and you might want to check with your instructor on that.