java - Java 中带有三位数字 key 的凯撒密码

标签 java encryption

我在这里发表的第一篇文章,所以请耐心等待。我必须修改凯撒密码的给定程序,使 key 为 3 位数字,而不是之前的 1 位。我的代码是:

/** Class for doing the encryption and decryption using the Caesar Cipher. */
public class CaesarCipher {
    protected char[] encoder = new char[26];    // Encryption Array
    protected char[] decoder = new char[26];    // Decryption Array
    protected int[] r_array = new int[3];
    /** Constructor that initializes the encryption and decryption arrays. */
    public CaesarCipher(int rotation) {     // function begins by changing input rotation into an array of digits
        String number = String.valueOf(rotation);
        for(int i = 0; i < number.length(); i++) {
            int r = Character.digit(number.charAt(i), 10);
            r_array[i] = r; // input changed to array
        }
        //TODO: fix three digit decryption
        for (int k = 0; k < 26; k+=3) {     
// Origianlly there was one for loop with a k++ that cycled through the rotation directly, as oppose to r_array.
            encoder[k] = (char) ('A' + (k + r_array[0]) % 26);
            decoder[k] = (char) ('A' + (k - r_array[0] + 26) % 26);
        }
        for (int k = 1; k < 26; k+=3) {
            encoder[k] = (char) ('A' + (k + r_array[1]) % 26);
            decoder[k] = (char) ('A' + (k - r_array[1] + 26) % 26);
        }
        for (int k = 2; k < 26; k+=3) {
            encoder[k] = (char) ('A' + (k + r_array[2]) % 26);
            decoder[k] = (char) ('A' + (k - r_array[2] + 26) % 26);
        }
    }
    /** Returns String representing encrypted message. */
    public String encrypt(String message) {
        return transform(message, encoder);     // use encoder array
    }
    /** Returns decrypted message given encrypted secret. */
    public String decrypt(String secret) {
        return transform(secret, decoder);      // use decoder array
    }
    /** Returns transformation of original String using given code. */
    private String transform(String original, char[] code) {
        char[] msg = original.toCharArray();
        for (int k=0; k < msg.length; k++) {
            if (Character.isUpperCase(msg[k])) {
                int j = msg[k] - 'A';
                msg[k] = code[j];
            }
            if (Character.isLowerCase(msg[k])) {
                int j = msg[k] - 'a';
                msg[k] = code[j];
            }
        }
        return new String(msg);
    }
}

然后有一个单独的主类。

public class CipherDriver {
    /** Simple main method for testing the Caesar cipher */
    public static void main(String[] args) {

        /** Uses user input to create new message */    // Added for practice
        Scanner input_1 = new Scanner(System.in);
        System.out.println("\nEnter desired message or enter 'DEFAULT' to use default message: ");
        String input_m = input_1.nextLine();
        String d_string = "DEFAULT";
        if (input_m.equals(d_string)) {     // builds a default message
            input_m = "CAESAR HAS NAMED SOMETHING AFTER HIMSELF, AGAIN.";
        }
        System.out.println("Encoding message... \n");

        /** Uses user input to assign new encryption key */
        Scanner input_2 = new Scanner(System.in);
        System.out.println("Enter three digit rotation to generate cipher: ");
        int rotation = input_2.nextInt();
        System.out.println("Generating cipher code... \n");

        CaesarCipher cipher = new CaesarCipher(rotation);
        String message = input_m;

        /** Uses user input to determine whether the user wishes to encrypt or decrypt the message */
        Scanner input_3 = new Scanner(System.in);
        System.out.println("1.  Encrypt \n2.  Decrypt \n3.  Encrypt then Decrypt \n " +
                "\nEnter number for desired function: ");
        int option = input_3.nextInt();
        if (option == 1) {
            System.out.println("Encrypting message... ");
            System.out.println("Message: " + message);
            System.out.println("Encryption code = " + new String(cipher.encoder));
            String coded = cipher.encrypt(message);
            System.out.println("Encrypted secret:  " + coded);
        }
        if (option == 2) {
            System.out.println("Decrypting message... ");
            System.out.println("Secret: " + message);
            System.out.println("Decryption code = " + new String(cipher.decoder));
            String answer = cipher.decrypt(message);
            System.out.println("Decrypted message:  " + answer);  //should print plaintext again
        }
        if (option == 3) {
            System.out.println("\nMessage: " + message);
            System.out.println("\nEncrypting message... \n");
            System.out.println("Encryption code = " + new String(cipher.encoder));
            String coded = cipher.encrypt(message);
            System.out.println("Encrypted secret:  " + coded);
            System.out.println("\nDecrypting message... \n");
            System.out.println("Decryption code = " + new String(cipher.decoder));
            String answer = cipher.decrypt(coded);
            System.out.println("Decrypted message:  " + answer);  //should print plaintext again
        }
    }
}

我收到的输出是不正确的。

Enter desired message or enter 'DEFAULT' to use default message: 
DEFAULT
Encoding message... 

Enter three digit rotation to generate cipher: 
123
Generating cipher code... 

1.  Encrypt 
2.  Decrypt 
3.  Encrypt then Decrypt 

Enter number for desired function: 
3

Message: CAESAR HAS NAMED SOMETHING AFTER HIMSELF, AGAIN.

Encrypting message... 

Encryption code = BDFEGIHJLKMONPRQSUTVXWYAZB
Encrypted secret:  FBGTBU JBT PBNGE TRNGVJLPH BIVGU JLNTGOI, BHBLP.

Decrypting message... 

Decryption code = ZZZCCCFFFIIILLLOOORRRUUUXX
Decrypted message:  CZFRZR IZR OZLFC ROLFUIIOF ZFUFR IILRFLF, ZFZIO.

如何让程序正确使用三位数 key ?

最佳答案

凯撒密码实际上不需要重新配置的字母表。当您获得字母表中的索引后,您只需添加/减去 key 值即可进行加密/解密。

对于输入中的每个字符:

  1. 将字符转换为字母表中的索引(在本例中为 ABC);
  2. 用数字 mod 字母表的大小执行模加法来加密 - 模减法来解密;
  3. 再次将新索引转换为字母表中的字符
  4. 将该字符添加到输出

这就是全部内容。

如果您想使用第一个数字加密第一个字符,使用第二个数字加密第二个字符,那么您需要为这些 key 单独重新配置字母。当前示例中的加密代码以B开头和结尾。想一想,这肯定不对吧?

关于java - Java 中带有三位数字 key 的凯撒密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60517163/

相关文章:

Java:序列化第二次不起作用

flutter - Android 上的 Diffie Hellman 和 AES

node.js - Node.js 中的 AES 加密和 Scala 中的解密

encryption - 使用 AES256 编译 System.Data.Sqlite

java - 如何存储 key 对并在其他类中使用它进行解密?

javascript - Nashorn 在 JDK10 Java.type() 中的奇怪行为

java - 在Java中使用正则表达式提取子字符串

java - 扩展DefaultTableCellRenderer,getTableCellRendererComponent中没有创建新对象?

java - 创建注释来执行常见操作并返回结果

java - 我正在写一个密码,但只有当我忽略空格时它才会起作用。有没有办法让它忽略空格?