【问题标题】:Understanding the Caesar Cipher code in Java理解 Java 中的凯撒密码
【发布时间】:2015-06-23 16:28:06
【问题描述】:

所以我只需要一点帮助来理解这段代码的工作原理。我从互联网上获得了这段代码,但虽然我完全理解凯撒密码的工作原理,但我无法清楚地理解它。不幸的是,它的代码版本对我来说有点神秘。如果有人能指导我了解这段代码的作用,那将非常有帮助。

public class CaesarCipherProgram{
public static void main(String[] args) {

    String str = "This is a secret";

    System.out.println( CaesarCipherProgram.encode( str, 3 ));
    System.out.println( CaesarCipherProgram.decode( CaesarCipherProgram.encode( str, 3), 3));
}

public static String decode(String enc, int offset) {
    return encode(enc, 26-offset);
}

public static String encode(String enc, int offset) {
    offset = offset % 26 + 26;
    StringBuilder encoded = new StringBuilder();
    for (char i : enc.toCharArray()) {
        if (Character.isLetter(i)) {
            if (Character.isUpperCase(i)) {
                encoded.append((char) ('A' + (i - 'A' + offset) % 26 ));
            } else {
                encoded.append((char) ('a' + (i - 'a' + offset) % 26 ));
            }
        } else {
            encoded.append(i);
        }
    }
    return encoded.toString();
}

}

我的问题:

首先,我不明白这里是如何使用模数运算符来获取我们的偏移量的:

offset = offset % 26 + 26;

其次,为什么使用StringBuilder而不是String进行连接?

最后,我对这行代码有点迷茫。这在加密过程中是如何工作的?我所知道的是,当消息中的大写字母被加密时,它应该返回一个大写值。

((char) ('A' + (i - 'A' + offset) % 26 ))

任何形式的帮助/解释都将不胜感激。

【问题讨论】:

    标签: java


    【解决方案1】:
    • 此处使用模运算符将值强制为介于 26 和 51(含)之间。 offset%26 介于 0 和 25 之间,加上 26 即可达到该范围。

    • StringBuilder 对于字符串比基本串联更有效,因为不需要为每个串联创建新对象。 append 用于添加,toString 用于获取字符串作为结果。

    • 字符也是数字类型。例如,(int)('B'-'A') 是 1,A+3 是 D,以此类推。大写字符是一个连续的块,而小写字符是一个单独的连续块。减法将字母 A-Z 转换为数字 0-25。加法和取模得到另一个数字 0-25,加上 'A' 得到一个字符 A-Z。

    【讨论】:

      【解决方案2】:

      这一行

      offset = offset % 26 + 26;
      

      涵盖了传入的offset 是否定的可能情况。在 Java 中,如果 % 运算符的第一个参数是否定的,则答案是否定的(或 0)。如果它是负数,那么offset % 26 会在-250 之间产生结果,因此添加26 会使其成为正数(重要的是,这里的结果是非负数)。这样,添加偏移量并稍后执行% 26 将确保生成的移位字符索引介于025 之间。

      StringBuilder 类在这里用作它的主要目的 - 构建一个 String 而不为每个添加的字符创建一个临时的 String 对象,浪费资源 - 处理时间和内存。

      char 数据类型可以转换(和考虑)为 int 值,即字符的 Unicode 值。大写字母'A''Z' 分别由代码6590 表示。从char 中减去'A' 得到一个介于025 之间的int。添加偏移量,另一个% 26 使加密的char 再次“环绕”到开头。例如。 'Z' + 3 => 25 + 3 => 28 => 2 => 'C'。您可以添加'A' 回以通过90 获取65。该值被转换回char,以便将正确的字符附加到StringBuilder

      【讨论】:

      • 在你的例子中,这是怎么发生的:28 => 2 => 'C' ?
      • 在转换为 char 之前还有另一个 % 26。
      • 是的,但我们是如何得到“C”的?那是等效的 unicode 值吗?
      • 28 % 262'A'65 被提升为int,而65 + 26767 被转换回char,即'C'
      猜你喜欢
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多