所以我需要一些帮助来理解这段代码是如何工作的。我从互联网上获得了这些代码,但我完全理解Caesar Cipher的工作原理我无法理解它。不幸的是,它的代码版本对我来说有点神秘。如果有人可以告诉我这段代码的用途,那将非常有用。
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();
}
}
我的问题:
首先,我不明白如何使用modolus运算符来获取我们的偏移量:
offset = offset % 26 + 26;
其次,为什么使用StringBuilder
代替String
进行连接?
最后,我对这行代码感到有点迷茫。这在加密过程中如何工作?我所知道的是,当消息中的大写字母被加密时,它应该返回一个大写值。
((char) ('A' + (i - 'A' + offset) % 26 ))
非常感谢任何形式的帮助/解释。
答案 0 :(得分:2)
此处使用模运算符来强制值介于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。
答案 1 :(得分:1)
这一行
offset = offset % 26 + 26;
涵盖传递的offset
为负数的可能情况。在Java中,如果%
运算符的第一个参数为负数,则答案将为负数(或0)。如果它是否定的,那么offset % 26
会在-25
和0
之间生成结果,因此添加26
会使其成为正数(这里的结果非负非常重要)。这样,添加偏移并稍后执行% 26
将确保生成的移位字符索引介于0
和25
之间。
这里使用StringBuilder
类作为其主要目的 - 构建String
而不为每个添加的字符创建临时String
对象,浪费资源 - 处理时间和内存。
char
数据类型可以转换(并且被认为)为int
值,该值是字符的Unicode值。大写字母'A'
到'Z'
分别由代码65
到90
表示。从'A'
中减去char
可为int
提供0
和25
之间的% 26
。添加了偏移量,另一个char
使加密的'Z' + 3
“环绕”再次开始。例如。 'C'
=> 25 + 3 => 28 => 2 => 'A'
。您可以添加65
以通过90
获取char
。该值将被强制转换为StringBuilder
,以便将正确的字符附加到curl -H "public-api-token: 049cxxxxxc026ef7364fa38c8792" -X PUT -d "urlToShorten=google.com" https://api.shorte.st/v1/data/url
。