3

I'm trying to get a program to encrypt a message using Cesar's Cypher, which involves replacing every character of a string with the letter, whose code is the code of the replaced letter plus 3. For e.g., if the letter is A, then it has to be replaced with D, because the code of D is the code of A plus 3. The letters are case-sensitive. The code I thought of uses a really heavy switch construct, I was wondering, if you could help me to make it more straight forward.

Here's the code I use for the encryption method:

public class Util 
{   

  public static String Encript(String stringa)

  {

        char[] stringaArray=stringa.toCharArray();


    for (int i =0; i<stringaArray.length; i++)
    {
        switch (stringaArray[i])
        {
                case 'a':
                        stringaArray[i]=('D');
                        break;
                case 'b':
                    stringaArray[i]='E';
                    break;
                case 'c':
                    stringaArray[i]='F';
                case 'd':
                    stringaArray[i]='G';
                    break;
                case 'e':
                    stringaArray[i]='H';
                    break;
                case 'f':
                    stringaArray[i]='I';
                    break;
                case 'g':
                    stringaArray[i]='J';
                    break;
                case 'h':
                    stringaArray[i]='K';
                    break;
                case 'i':
                    stringaArray[i]='L';
                    break;
                case 'j':
                    stringaArray[i]='M';
                    break;
                case 'k':
                    stringaArray[i]='N';
                    break;
                case 'l':
                    stringaArray[i]='O';
                    break;
                case 'm':
                    stringaArray[i]='P';
                    break;
                case 'n':
                    stringaArray[i]='Q';
                    break;
                case 'o':
                    stringaArray[i]='R';
                    break;
                case 'p':
                    stringaArray[i]='S';
                    break;
                case 'q':
                    stringaArray[i]='T';
                    break;
                case 'r':
                    stringaArray[i]='U';
                    break;
                case 's':
                    stringaArray[i]='V';
                    break;
                case 't':
                    stringaArray[i]='W';
                    break;
                case 'u':
                    stringaArray[i]='X';
                    break;
                case 'v':
                    stringaArray[i]='Y';
                    break;
                case 'w':
                    stringaArray[i]='Z';
                    break;
                case 'x':
                    stringaArray[i]='A';
                    break;
                case 'y':
                    stringaArray[i]='B';
                    break;
                case 'z':
                    stringaArray[i]='C';
                    break;

        }

  }
    String encripted= new String(stringaArray);
    return encripted;


 }

}

Then I use this method in the graphical interface class so that it acts when a button is pressed like this:

 private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {                                      
    String stringa=messageTxt.getText();

    encriptedTxt.setText(Util.Encript(stringa, encriptedTxt));


}            

Here is an example of test-case:

Test case:
aBxyE    //Input
dEabH    //Output

Thank you in advance!

5
  • 2
    Yes that's a terrible way to do that. Commented Jul 11, 2016 at 4:11
  • What is your question? You've just posted a bunch of code and then thanked us? Commented Jul 11, 2016 at 4:28
  • @LukePark I was wondering if you could point me towrds a lighter way of writing it Commented Jul 11, 2016 at 4:30
  • A HashMap would be a fast way. Loop through each character and retrieve the value that corresponds to that character as a key. Also, I'm sure you know this already, but using this cipher in production is a big no no. Don't do it. Commented Jul 11, 2016 at 4:33
  • @LukePark Yeah, I was just playing around and see how efficient it could get, thanks for the idea, I'm a bit of a rookie, so I haven't thought of that, to be honest... Commented Jul 11, 2016 at 4:36

3 Answers 3

1

Khoor/#Zruog

You could iterate the characters in the String, and I would also pass in the key offset. Create a StringBuilder and append each character after performing integer addition and casting. Something like,

public static String encrypt(String msg, int key) {
    StringBuilder sb = new StringBuilder();
    for (char ch : msg.toCharArray()) {
        char c = (char) (ch + key);
        sb.append(c);
    }
    return sb.toString();
}

Decryption is trivial with a Caesar cipher; you can call encrypt with the negative value of the key

public static String decrypt(String msg, int key) {
    return encrypt(msg, -key);
}

And I tested my example with

public static void main(String[] args) {
    String msg = encrypt("Hello, World", 3);
    System.out.println(msg);
    System.out.println(decrypt(msg, 3));
}

Finally, as others have noted, the Caesar cipher is terribly insecure (because letter frequency is not perturbed, it's trivial in a modern sense).

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, of course, but I was not to use it in future projects, I was just trying to get it to work as effeciently as possible. Thank you a lot!
This is an elegant solution. It does not limit the scope of the chars used to the alphabet though. This can be an advantage or dis advantage, depending on the OP need.
1

This code will sawp a char with another one three chars apart, as defined in ALPHABET :

public class Util
{

    private final static String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    public static String encript(String stringa)

    {
        char[] stringaArray = stringa.toCharArray();

        for (int i =0; i<stringaArray.length; i++) {

            char c = stringaArray[i];
            int index = ALPHABET.indexOf(c);

            if(index <0)
             {
                continue ; //if c does not appear in ALPHABET
            }
                                    // for example c is *, leave it unchanged
            if((index +3) >= ALPHABET.length() ) {
                index = index - ALPHABET.length();
            }

            stringaArray[i] = ALPHABET.charAt(index+3);
        }

        String encripted= new String(stringaArray);
        return encripted;
    }

}

If it is not clear, do not hesitate to ask.

3 Comments

Do you think using ASCII codes is a valid way of doing it?
Like sobstituting c with an int and then subracting 29 (The differents between the placesof the letters I need to exchange) and then going back to set the value of stringaArray[i]=(char) c ?
Look at Elliott Frisch's solution. You can do char+int. best would be try and post another question if needed.
1

Here is my Short and Efficient code for your program:

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

public class Solution {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //N is length of string
        int N = Integer.parseInt(br.readLine());
        //Reading string Input
        String str = br.readLine();
        //K is the key to rotate characters in the string
        //In your case K = 3
        int K = Integer.parseInt(br.readLine());
        K %= 26;    //Incase K is greater than 25
        //Main [tag:algorithm]
        for(int i = 0; i < N; i++){
            char c = str.charAt(i);
            if(c >= 65 && c <= 90){
                c += K;
                if(c > 90){
                    c = (char)(c - 90 + 64);
                }
            }
            if(c >= 97 && c <= 122){
                c += K;
                if(c > 122){
                    c = (char)(c - 122 + 96);
                }
            }
            System.out.print(c);
        }
    }
}

I am doing k = k % 26 because if the k = 26 then it will print the same letter, if k = 27 the character will rotate only 1 time and so on.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.