Caesar cipher decoder in Java - unexpected output

55 views Asked by At

I'm trying to write a Caesar cipher decoder in Java, but I get unexpected output (see below example).

The BetterDecrypt() method takes a string cipherText to be decoded, as well as an integer shiftKey that is the number of places up or down the alphabet each character of the string is to be shifted. If a character is not in String ALPHABET = "abcdefghijklmnopqrstuvwxyz", then I want to keep the character as is, eg "ab4c" should be decoded "bc4d".

import java.io.*;
import java.util.*;

public class SimpleDecoder {
    public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";

    public static String BetterDecrypt(String cipherText, int shiftKey) {
        cipherText = cipherText.toLowerCase();
        String message = "";
        for (int ii = 0; ii < cipherText.length(); ii++) {
            char character = cipherText.charAt(ii);
            if (ALPHABET.contains(Character.toString(character))) {
                int charPosition = ALPHABET.indexOf(cipherText.charAt(ii));
                int keyVal = (charPosition - shiftKey) % 26;
                if (keyVal < 0) {
                    keyVal = ALPHABET.length() + keyVal;
                char replaceVal = ALPHABET.charAt(keyVal);
                message += replaceVal;
                }
            } else {
                message += character;
            }
        }
        return message;
    }

    public static void main(String[] args) {
        System.out.println(BetterDecrypt("ab4c", -1));
        // OUTPUT: 4   EXPECTED OUTPUT: bc4d
        System.out.println(BetterDecrypt("ab4c", 1));
        // OUTPUT: z4  EXPECTED OUTPUT: za4b
    }
}
2

There are 2 answers

0
BoppreH On BEST ANSWER

Your keyVal < 0 condition is wrapping too much code:

                if (keyVal < 0) {
                    keyVal = ALPHABET.length() + keyVal;
                char replaceVal = ALPHABET.charAt(keyVal);
                message += replaceVal;
                }

It should be

                if (keyVal < 0) {
                    keyVal = ALPHABET.length() + keyVal;
                }
                char replaceVal = ALPHABET.charAt(keyVal);
                message += replaceVal;

Otherwise, you'll omit all shifted characters that don't wrap around from a -> z.

0
Grinding For Reputation On

You're not doing anything if keyVal is greater than 0. Here's the easiest possible fix

if(keyVal < 0) {
    keyVal = ALPHABET.length() + keyVal;
    char replaceVal = ALPHABET.charAt(keyVal);
    message += replaceVal;
}
else
    message += ALPHABET.charAt(keyVal);