LauTN 2013-03-07 08:10 采纳率: 0%
浏览 1413

一个凯撒密码的char运算的问题

这是从原问题中扩展出来的,因为还有更多不明白的地方,而且不容易在评论里讨论,所以重新开一个题目。
问题背景:
可以运行的原代码 CODE[A] return ( (char) ('A' + ((ch -'A' + key) % 26)) );运行位置在 private char encryptChar(char ch, int key){} 中。

无法输出的代码 CODE [B] return ( (char) ((ch+ key) % 26) );按@xiaoyan_12解释:

添加'A'是确保"encryptChar" 方法的结果在 ASCII 范围64 to 90(A (CAPITAL) to Z (CAPITAL))是一个有效的字符。在你的代码中减去'A'也可以忽略,('A' + ((ch + key) % 26))也会运行。

问题一: 它的运算过程是怎样的呢,只是求余数的时候少减去了'A',为什么加密结果错了15位?
CODE [C]: return ( (char) ('A'+((ch+ key) % 26)) );
运行结果是

Enter line: ABC
Enter key: 1
The result is: OPQ
newplain:ABC

问题二: 既然添加'A'是确保"encryptChar" 方法的结果是一个有效的字符。所以我使用了CODE[D] ( (char) ('A'+(((ch+ key) % 26) - 'A')));以及转换了括号位置( (char) ('A'+(((ch+ key) % 26) - 'A'))); 我也试过( (char) ('B'+(((ch+ key) % 26) - 'A'))); 但都无法输出有效字符。
CODE[D] 只比 CODE[C]多了- 'A'为什么也不能输出字符了呢?
运行结果是

Enter line: ABC
Enter key: 1
The result is:
newplain:

自学JAVA,提问不清晰请见谅。
代码:

 public void run() {    
        setFont("Arial-PLAIN-24");
        String line = readLine ("Enter line: ");
        int key = readInt ("Enter key: ");
        String siphertext = encryptCaesar(line , key);
        println("The result is: " + siphertext);
        String newplain = encryptCaesar(siphertext , -key);
        println("newplain:" + newplain);    
    }

    private String encryptCaesar(String str , int key){
        if(key < 0){
            key = 26 - ( -key % 26 );
        }

        String result = "";
        for(int i = 0; i < str.length(); i++){
            char ch = str.charAt(i);        
            result += encryptChar(ch,key);
        }
        return result;
    }

    private char encryptChar(char ch, int key){
        if(Character.isUpperCase(ch)){
            return (  (char) ('A' + ((ch -'A' + key) % 26))  );
        }
        return ch;
    }`enter code here`
  • 写回答

1条回答 默认 最新

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2022-12-21 13:41
    关注

    ChatGPT尝试为您解答,仅供参考
    为了回答你的问题,我需要先解释下这个程序的加密算法是怎么工作的。

    这个程序使用的是恺撒密码,它是一种简单的加密算法,可以将一个字符串中的每个字符都移动到英文字母表中的固定位置。

    具体来说,对于英文字母表中的每个字母,将它向后移动固定数量的位置(即密钥),就可以得到加密后的字符。例如,如果密钥是1,那么A就会被移动到B的位置,B就会被移动到C的位置,以此类推。


    那么,对于你的问题来说,第一个问题,为什么代码C的结果和代码A的结果相差15位,就是因为在代码C中,你没有减去'A',所以字符的范围是从0到25,而在代码A中,你减去了'A',所以字符的范围是从'A'到'Z'。

    例如,在代码C中,如果密钥是1,那么A会被加密成1,B会被加密成2,以此类推,所以A会变成O,B会变成P,以此类推。


    对于第二个问题,为什么代码D无法输出有效字符,是因为在代码D中,你使用的是这样的表达式:

    (char) ('A'+(((ch+ key) % 26) - 'A'))

    在这个表达式中,你首先将字符ch和密钥key相加,然后取模26,再减去'A',最后加上'A'。

    这个表达式的问题在于,减去'A'后,得到的值可能是负数,而在Java中,如果将负数转换为字符,它会被转换成一个不可见的字符。所以,这个表达式得到的字符是无效的。


    为了解决这个问题,你可以使用代码A中的表达式,即:

    (char) ('A' + ((ch -'A' + key) % 26))


    这个表达式首先将字符ch减去'A',得到的值就是字符ch在英文字母表中的位置。然后再将这个值加上密钥,然后再取模26,最后再加上'A'。这样,就可以保证得到的字符是一个有效的英文字母。

    所以,如果你想要使用恺撒密码加密英文字母,最好使用代码A中的表达式。

    评论

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突