不正确的字符串加密/解密

时间:2018-06-28 13:40:16

标签: java arrays string encryption

我创建了这个程序,以使用String作为用户输入,并将单词的每个字符与另一个特定的字符交换来创建另一个单词。

但是输出与输入相同。

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]);
        }
    }
}

7 个答案:

答案 0 :(得分:3)

问题出在内部循环中。

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

这适用于在字母的后半部分找到的输入。但是,当在字母的前半部分找到一个字母时,首先将其替换,然后循环继续进行,找到新字母并将其替换为原始字母。 (将A替换为Z,然后在循环的后续迭代中找到Z,然后将其替换为A。)

添加一个中断以在完成一次替换后退出此循环。

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

答案 1 :(得分:2)

如果只使用简单的字符算术,则可以使您的生活更加轻松。这样就完全消除了两个数组的声明及其迭代:

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');
    }
}

此代码将把字母表中的每个字母与其“对应”交换。例如。 'Z'将被加密为'A',依此类推。我还添加了相同的逻辑来支持小写。

其背后的“数学”非常简单。它通过将char转换为其ASCII值来工作。这是在Java中隐式完成的。参见示例:

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

将打印65,因为A的ASCII值为65。

答案 2 :(得分:0)

因为在您的arrencryptarrdecrypt中,所有chars都是大写的。这意味着仅大写字母将被替换。因此,要么更改

char[] arr=word.toCharArray();

收件人

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

或者在您的chars中将arrays小写

进行此更改:

Input: "String"

Output: "HGIRMT"

答案 3 :(得分:0)

条件错误,您需要使用break停止内部循环,否则替换将继续并且输出将错误。

if (arr[i] == arrencrypt[j]){
    arr[i] = arrdecrypt[j];
    break;
}

此外,您可以将小写输入Hello world与数组中的大写字符进行比较-这样输出也将是错误的。我建议您也将输入也转换为大写:

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

如果要保留正确的大小写,请执行以下操作:

String[] 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"};
String[] 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"};

String word="Hello world";          // sample input
String[] split = word.split("");

StringBuilder output = new StringBuilder();
for (String character: split) {
    for (int i=0; i<arrencrypt.length; i++) {
        if (character.equals(arrencrypt[i].toUpperCase())) {
            output.append(arrdecrypt[i].toUpperCase());
            break;
        } else if (character.equals(arrencrypt[i].toLowerCase())) {
            output.append(arrdecrypt[i].toLowerCase());
            break;
        }
        if (i == arrencrypt.length - 1) {
            output.append(character);
        }
    }
}
System.out.println(output.toString());    // Svool dliow

答案 4 :(得分:0)

获取的数组是String的内部char数组的副本,因此更改数组不会更改String。这确实是一种祝福。

    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]);
    }

在不中断的情况下,对于后来的j,更改的char可以使条件成立。 然后再次转换。不幸的是,在这里两次加密会产生原始字母。


或者

    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();

答案 5 :(得分:0)

尝试

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);
        }
    }
}
  

输出

Enter the encrypted word:
Hello
Svool

因为您只有大写字母,所以失败了

答案 6 :(得分:0)

尝试以下解决方案: 首先,您要初始化地图,其中密钥是加密字母,值是解密字母,然后提供单词和程序替换字母并打印输出。初始化地图只需将ASCII码转换为Char,然后转换为String即可将其放入地图

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;
}