3

I've written this simple program including a method for encoding a message (Caesar's cipher)... doesn't work though, and I think it has something to do with my if condition for letters that become offset past 'Z' (and thus reset to the beginning of the alphabet).

I've found other code for Caesar's cipher on the web which uses StringBuilders and other methods that I haven't learned yet. That's just great and I look forward to getting there one day, but in the meantime, what's going wrong with my code?

No need to give me the answer, but a hint would be much appreciated. :)

 import java.util.*;
 class Exercice4 {

public static void main(String[] args) {

     Scanner sc = new Scanner(System.in);

     System.out.println("Enter a message:");
     String msg = (sc.nextLine()).toUpperCase();

     System.out.println("Enter a value for K:");
     int k = sc.nextInt();

     caesar(msg, k);


}

 public static void caesar(String A, int B) {

     char str[]=A.toCharArray();
     String alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     for (int i=0; i<A.length(); i++) {
         for (int j=0; j<26; j++) {
             if (alpha.charAt(j) == str[i]) {
                 if ((j+B)>25) {
                     str[i] = alpha.charAt(j + B - 26);
                 } else {
                     str[i] = alpha.charAt(j + B);
                 }
             }
         }  
     }
     String code = new String (str);
     System.out.println("Here is your encoded message: ");
     System.out.println(A);
     System.out.println(code);
 }
} 
ktouchie
  • 371
  • 1
  • 3
  • 9

2 Answers2

3

When you look (second for-loop) for a letter and find it, you must exit the bucle to avoid repeating the sustitutions.

For example, if the input string is "A" and k = 2:

You look for the letter A inside alpha and change it by the letter C. As the bucle continues iterating alpha you find C and change it by E. Etc.

Place a breakpoint and follow the execution step by step.

Paco Abato
  • 3,920
  • 4
  • 31
  • 54
  • That's great, it works perfectly now, thank you! I'm just trying to understand now: if I was stuck in the second loop repeating substitutions, why wasn't it an infinite loop? – ktouchie Dec 15 '15 at 13:27
  • 1
    Because the iteration limits are static (A.length in the first loop and 26 in the second one). – Paco Abato Dec 15 '15 at 13:29
  • 1
    And indexes i and j are never decremented so they always reach the limit of the iterations. – Paco Abato Dec 15 '15 at 13:30
-1

While your implementation can work given the right offset numbers, you could try something a little simpler.

All you need to know is that a character can be interpreted as an integer without any black magic in between.

char x = 'A'; 
System.out.println((int) x); //65

Using this to our advantage we can implement caesar like this:

public static String caesar(String A, int B) {
    char[] newString = A.toCharArray();
    for(int i = 0; i < A.length(); i++){
        int newChar = newString[i]+B;
        while(newChar > 65+26) // 65 = A, 26 = number of letters in the alphabet
            newChar -= 26;

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

    }
    return new String(newString);
}
nitowa
  • 1,079
  • 2
  • 9
  • 21