1

I created this program to take a String as user input and swap each character of the word with another specific character to create a different word.

But the output is the same as the input.

import java.util.Scanner;

class Encrypt{

    public static void main(String[] args){

        char[] arrencrypt={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
        char[] arrdecrypt={'Z','Y','X','W','V','U','T','S','R','Q','P','O','N','M','L','K','J','I','H','G','F','E','D','C','B','A'};

        Scanner sc=new Scanner(System.in);
        System.out.println("Enter the encrypted word:");
        String word=sc.nextLine();
        char[] arr=word.toCharArray();
        for(int i=0;i<arr.length;i++){
            for(int j=0;j<arrencrypt.length;j++){
                if(arr[i]==arrencrypt[j]){
                    arr[i]=arrdecrypt[j];
                }
            }
        }
        for(int k=0;k<arr.length;k++){
            System.out.print(arr[k]);
        }
    }
}
1
  • 1
    What is the purpose of if(arr[i]==arrencrypt[j]) ? Commented Jun 28, 2018 at 13:42

6 Answers 6

3

The problem is in the inner loop.

for(int j=0;j<arrencrypt.length;j++){
    if(arr[i]==arrencrypt[j]){
        arr[i]=arrdecrypt[j];
    }
}

This works for inputs that are found in the second half of the alphabet. But when a letter is found in the first half of the alphabet, first it gets replaced, then the loop keeps going and finds the new letter and replaces it with the original letter. (A gets replaced with Z, but then the Z is found in a later iteration of the loop and is replaced with A.)

Add a break to get out of this loop after a single replacement has been done.

for(int j=0;j<arrencrypt.length;j++){
    if(arr[i]==arrencrypt[j]){
        arr[i]=arrdecrypt[j];
        break;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can make your life a lot easier, if you just use simple character arithmetics. This eliminates the declaration of the two arrays and their iteration completly:

for(int i = 0; i < arr.length; i++){
    char c = arr[i];
    if(Character.isLowerCase(c)){
        arr[i] = (char) ('z' - c + 'a');
    } else if(Character.isUpperCase(c)){
        arr[i] = (char) ('Z' - c + 'A');
    }
}

This code will swap every letter in the alphabet with its "counterpart". E.g. 'Z' will be encrypted to 'A' and so on. I also added the same logic to support lowercase.

The "math" behind it is pretty easy. It works by converting the char to its ASCII-value. This is done implicitly in java. See the example:

int i = 'A';
System.out.println(i);

Will print 65 because the ASCII value of A is 65.

1 Comment

Nice solution without arrays
0

The gotten array is a duplicate of the internal char array of the String, so changing the array will not change the String. This indeed is a blessing.

    char[] arr = word.toCharArray();
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arrencrypt.length; j++){
            if (arr[i] == arrencrypt[j]) {
                arr[i] = arrdecrypt[j];
                break;
            } else if (arr[i] == Character.toLowerCase(arrencrypt[j])) {
                arr[i] = Character.toLowerCase(arrdecrypt[j]);
                break;
            }
        }
    }
    String word2 = new String(arr);
    System.out.printf("Word '%s' is decrypted as: '%s'%n", word, word2);
    for(int k=0;k<arr.length;k++){
        System.out.print(arr[k]);
    }

Without break, the condition can become true with the changed char for a later j. And then it is converted again. Unfortunately here twice encrypting yield the original letter.


Alternatively

    String arrencrypt = "ABCDEFG...XYZ";
    String arrdecrypt = "ZYX...GFEDCBA";
    StringBuilder sb = new StringBuilder(word.length());
    for (int i = 0; i < word.length(); i++) {
        char ch = word.charAt(i);
        int j = arrencrypt.indexOf(ch);
        if (j != -1) {
            ch = arrdecrypt.charAt(j);
        }
        sb.append(ch);
    }
    String word2 = sb.toString();

Comments

0

try this

import java.util.Scanner;

public class A {
    public static void main(String[] args) {
        char[] arrencrypt = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
        char[] arrdecrypt = { 'Z', 'Y', 'X', 'W', 'V', 'U', 'T', 'S', 'R', 'Q', 'P', 'O', 'N', 'M', 'L', 'K', 'J', 'I',
                'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A' };
        try (Scanner sc = new Scanner(System.in)) {
            System.out.println("Enter the encrypted word:");
            String word = sc.nextLine();
            char[] arr = word.toCharArray();
            for (int i = 0; i < arr.length; i++) {
                char ch = arr[i];
                if (ch >= 'A' && ch <= 'Z') {
                    for (int j = 0; j < arrencrypt.length; j++) {
                        if (arrencrypt[j] == arr[i]) {
                            arr[i] = arrdecrypt[j];
                            break;
                        }
                    }
                } else {
                    char temp = Character.toUpperCase(arr[i]);
                    for (int j = 0; j < arrencrypt.length; j++) {
                        if (arrencrypt[j] == temp) {
                            arr[i] = Character.toLowerCase(arrdecrypt[j]);
                            break;
                        }
                    }
                }
            }
            for (char ch : arr)
                System.out.print(ch);
        }
    }
}

Output

Enter the encrypted word:
Hello
Svool

as you have only upper case letters so it was failing

1 Comment

char temp = ("" + arr[i]).toUpperCase().charAt(0); is a really bad way of converting a lowercase character to an upper one. Prefer to just use Character.toUpperCase()
0

Because of that in your arrencrypt and arrdecrypt all the chars are uppercase. This means that only upper case letters will be replaced. So either change

char[] arr=word.toCharArray();

To

char[] arr=word.toUpperCase().toCharArray();

Or make the chars lowercase in your arrays

With this change:

Input: "String"

Output: "HGIRMT"

1 Comment

@Lino As they say in programming.. oops.
0

Try this solution: First you initialize your map where key is encrypted letter and value is decrypted letter, than you provide your word and program replace letters and print output. Initialize map just convert ASCII number to Char and then to String to put it into map

public class Encrypt {

    public static void main(String[] args) {
       Map<Character, Character> map = initializeMap();
       StringBuilder output = new StringBuilder();
       Scanner sc = new Scanner(System.in);
       System.out.println("Enter the encrypted word:");
       String word = sc.nextLine();

       for (char s : word.toCharArray()) {
          output.append(map.get(s));
       }

       System.out.println(output.toString());
   }

   private static Map<Character, Character> initializeMap() {
      Map<Character, Character> map = new HashMap<>();
      for (int i = 65; i <= 90; i++) {
         map.put((char) i, (char) (155 - i));
      }
      for (int i = 97; i <= 122; i++) {
         map.put((char) i, (char) (219 - i));
      }

    return map;
}

1 Comment

why not use a Map<Character, Character> would be a lot nicer, wouldn't it?

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.