凯撒密码与三位数字密钥的Java实现

huangapple 未分类评论71阅读模式
标题翻译

Caesar Cipher with Three-Digit Key in Java

问题

/** 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) {
        String number = String.valueOf(rotation);
        // Ensure that the rotation has three digits by padding with zeros if needed
        while (number.length() < 3) {
            number = "0" + number;
        }
        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++) {
            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++) {
            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++) {
            encoder[k] = (char) ('A' + (k + r_array[2]) % 26);
            decoder[k] = (char) ('A' + (k - r_array[2] + 26) % 26);
        }
    }
    
    // ... (rest of the code remains unchanged)
}

The main issue was that the rotation digits weren't correctly handling three-digit rotations. I've modified the code in the constructor to ensure that the rotation is a three-digit number by padding it with zeros if necessary. This way, the rotation digits will be correctly assigned to r_array[0], r_array[1], and r_array[2].

英文翻译

My first post ever here, so bear with me. I have to modify a given program for a Caesar Cipher to make the key 3 digits as opposed to its previous 1. The code I have is:

/** 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 &lt; 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 &lt; 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) (&#39;A&#39; + (k + r_array[0]) % 26);
            decoder[k] = (char) (&#39;A&#39; + (k - r_array[0] + 26) % 26);
        }
        for (int k = 1; k &lt; 26; k+=3) {
            encoder[k] = (char) (&#39;A&#39; + (k + r_array[1]) % 26);
            decoder[k] = (char) (&#39;A&#39; + (k - r_array[1] + 26) % 26);
        }
        for (int k = 2; k &lt; 26; k+=3) {
            encoder[k] = (char) (&#39;A&#39; + (k + r_array[2]) % 26);
            decoder[k] = (char) (&#39;A&#39; + (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 &lt; msg.length; k++) {
            if (Character.isUpperCase(msg[k])) {
                int j = msg[k] - &#39;A&#39;;
                msg[k] = code[j];
            }
            if (Character.isLowerCase(msg[k])) {
                int j = msg[k] - &#39;a&#39;;
                msg[k] = code[j];
            }
        }
        return new String(msg);
    }
}

Then there was a separate class for the main.

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(&quot;\nEnter desired message or enter &#39;DEFAULT&#39; to use default message: &quot;);
        String input_m = input_1.nextLine();
        String d_string = &quot;DEFAULT&quot;;
        if (input_m.equals(d_string)) {     // builds a default message
            input_m = &quot;CAESAR HAS NAMED SOMETHING AFTER HIMSELF, AGAIN.&quot;;
        }
        System.out.println(&quot;Encoding message... \n&quot;);

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

        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(&quot;1.  Encrypt \n2.  Decrypt \n3.  Encrypt then Decrypt \n &quot; +
                &quot;\nEnter number for desired function: &quot;);
        int option = input_3.nextInt();
        if (option == 1) {
            System.out.println(&quot;Encrypting message... &quot;);
            System.out.println(&quot;Message: &quot; + message);
            System.out.println(&quot;Encryption code = &quot; + new String(cipher.encoder));
            String coded = cipher.encrypt(message);
            System.out.println(&quot;Encrypted secret:  &quot; + coded);
        }
        if (option == 2) {
            System.out.println(&quot;Decrypting message... &quot;);
            System.out.println(&quot;Secret: &quot; + message);
            System.out.println(&quot;Decryption code = &quot; + new String(cipher.decoder));
            String answer = cipher.decrypt(message);
            System.out.println(&quot;Decrypted message:  &quot; + answer);  //should print plaintext again
        }
        if (option == 3) {
            System.out.println(&quot;\nMessage: &quot; + message);
            System.out.println(&quot;\nEncrypting message... \n&quot;);
            System.out.println(&quot;Encryption code = &quot; + new String(cipher.encoder));
            String coded = cipher.encrypt(message);
            System.out.println(&quot;Encrypted secret:  &quot; + coded);
            System.out.println(&quot;\nDecrypting message... \n&quot;);
            System.out.println(&quot;Decryption code = &quot; + new String(cipher.decoder));
            String answer = cipher.decrypt(coded);
            System.out.println(&quot;Decrypted message:  &quot; + answer);  //should print plaintext again
        }
    }
}

The outputs I've been recieving have been, well, incorrect.

Enter desired message or enter &#39;DEFAULT&#39; 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.

How can I make the program correctly utilize a three-digit key?

答案1

得分: 0

重新配置的字母表对凯撒密码实际上是不必要的。当你在字母表中获得索引后,加/减密钥值就可以进行加密/解密。

对于输入中的每个字符:

  1. 将字符转换为字母表中的索引(在这种情况下是ABC);
  2. 执行模运算加法,用数字对字母表的大小取模以进行加密 - 执行模运算减法以进行解密;
  3. 将新索引再次转换为字母表中的字符;
  4. 将该字符添加到输出中。

就是这样了。

如果你想用第一个数字加密第一个字符,用第二个数字加密第二个字符,那么你需要为这些密钥使用单独重新配置的字母表。在你的示例中,"加密"代码以"B"开头并以"B"结尾。仔细考虑一下,这肯定是不正确的。

英文翻译

The reconfigured alphabets are really not required for the Caesar cipher. You can just add / subtract the key value for encryption / decryption when you've obtained the index in the alphabet.

For each character in input:

  1. convert character to index in alphabet (in this case the ABC);
  2. perform modular addition with the digit mod the size of the alphabet to encrypt - modular subtraction for decryption;
  3. convert new index to character in alphabet again
  4. add that character to the output

And that's all there is to it.

If you want to encrypt the first character with the first digit, and the second with the second digit then you need separate reconfigured alphabets for those keys. Current in your example the encryption code begins and ends with a B. Think about that for a second, that can surely not be right?

huangapple
  • 本文由 发表于 2020年3月4日 07:46:47
  • 转载请务必保留本文链接:https://java.coder-hub.com/60517163.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定