1

I have to Implement a static public method named encodeCaesar in the class Functionality.java, which encodes a text using Caesar encryption and I am a complete novice in Java.

Signature: encodeCaesar(String s, int val) : String

The method gets a string value and an integer value as input parameters. The letters (characters) from the string value are to be shifted by the integer value. For simplicity, I can assume that there are only letters and no spaces, numbers or special characters.

The string value should be converted to lower case before the encryption is performed. The method should return a string where each letter has been moved according to the specified integer value.

Example: encodeCaesar("Ac",3) returns "df". If the given integer value is less than 0 or greater than 26, an empty string should be returned.

public class Functionality {
    public static void main(String[] args) {
    }

    public static String encodeCaesar(String s, int val) {
        char[] newString = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            int newChar = newString[i] + val + 26;

            // Handle uppercase letters
            while (Character.isUpperCase(newString[i]) && newChar >= 65 + 26) {
                newChar -= 26;
            }

            // Handle lowecase letters
            while (Character.isLowerCase(newString[i]) && newChar >= 97 + 26) {
                newChar -= 26;
            }

            newString[i] = (char) (newChar);
        }

        return String.valueOf(newString);
    }
}

My problem is that in return it give me only true or false. How can I solve this: The method should return a string where each character has been moved according to the specified integer value.

3 Answers3

0
public static String caesar(String s, int val) {
    char[] newString = s.toLowerCase().toCharArray();
    for (int i = 0; i < s.length(); i++) {
        int newChar = newString[i] + val + 26;
        // Handle lowercase letters
        while (Character.isLowerCase(newString[i]) && newChar >= 97 + 26) {
            newChar -= 26;
        }
        newString[i] = (char) (newChar);
    }
    return String.valueOf(newString);
}

I solved the problem.

Community
  • 1
  • 1
0

The following code snippet addresses some minor issues:

  • non-letter characters (if any) remain unchanged by the cipher
  • while loop replaced with if
  • use modulo operator to wrap values over z
public static String encodeCaesar(String s, int val) {
    char[] newString = s.toLowerCase().toCharArray();
    for (int i = 0; i < newString.length; i++) {
        char newChar = newString[i];

        if (newChar >= 'a' && newChar <= 'z') {
            newString[i] = (char) ('a' + (newChar + val - 'a') % 26); 
        }
    }

    return new String(newString); // String.valueOf calls it anyway
}

Comparison:

System.out.println("encode: " + encodeCaesar("Viva Caesar! Morituri te salutant!", 3));
System.out.println("caesar: " + caesar("Viva Caesar! Morituri te salutant!", 3));

Output:

encode: ylyd fdhvdu! prulwxul wh vdoxwdqw!
caesar: ylyd=fdhvdu>=prulwxul=wh=vdoxwdqw>

Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
0

You can use String.codePoints method to iterate over int values of the characters of this string, and shift them by a given value:

public static String encodeCaesar(String s, int val) {
    if (val < 0 || val > 26) return "";
    return s.codePoints()
            // Stream<Character>
            .mapToObj(i -> (char) i)
            // convert to lowercase
            .map(Character::toLowerCase)
            // filter out non-letters
            .filter(ch -> ch >= 'a' && ch <= 'z')
            // if a letter should be shifted
            // outside the alphabetical range,
            // then move it before the beginning
            .map(ch -> ch + val > 'z' ? ch - 'z' + 'a' - 1 : ch)
            // shift letter by a given value
            .map(ch -> ch + val)
            // each character as a single string
            .map(Character::toString)
            // join characters into one string
            .collect(Collectors.joining());
}
public static void main(String[] args) {
    System.out.println(encodeCaesar("Ac", 3)); // df
    System.out.println(encodeCaesar("YZx 32*d", 3)); // bcag
}

See also: Replace non ASCII character from string