请有人解释下面突出显示的代码行。我根本不明白这条线是如何工作的。
您可以使用此示例来帮助我:
input: ATTACK keyword: LEMON res: LXFOPV
我不明白该行如何帮助将A
编码为L
以及其他字母......
ACSII参与?
static String encrypt(String text, final String key) {
String res = "";
text = text.toUpperCase();
for (int i = 0, j = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c < 'A' || c > 'Z') continue;
////////////////////////////////////////////////////////////////////////////
//please someone explain this line
res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
////////////////////////////////////////////////////////////////////////
j = ++j % key.length();
}
return res;
}
答案 0 :(得分:5)
代码使用字母的ASCII值。字母A-Z是ASCII值65-90。
这个想法是将两个字母加在一起,但如果值超过90(称为modular arithmetic),则会回绕。所以91实际上应该是65(即Z + 1 = A
)。
Java提供了%
运算符来进行模运算(x % n
)。但是,这适用于0→ n-1 的数字范围。因此,如果我们从每个字母中减去65,那么我们将在0→25范围内工作。这允许我们使用模数运算符(x % 26
)。
这就是代码正在做的事情:
c + key.charAt(j) - 2 * 'A'
这部分将两个字母加在一起,但也从每个字母中减去65个字母。如果写成:
,可能更容易理解(c - 'A') + (key.charAt(j) - 'A')
您会注意到- 'A'
可以- 65
作为(c + key.charAt(j) - 2 * 'A') % 26
的便捷方式。
现在我们有一个从零开始的值,但可能大于25.所以我们然后将其模数化:
(c + key.charAt(j) - 2 * 'A') % 26 + 'A'
然后我们需要将65添加回该值,以使其回到ASCII的A-Z范围:
char
剩下的唯一步骤是将其转换为int
,因为默认情况下结果为res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
:
ATTACK
如果输入为LEMON
且关键字为T
,那么在某些时候我们将不得不考虑输入字母M
(ASCII 84)和关键字母{ {1}}(ASCII 77)。
从每个减去65,我们得到T = 19和M = 12。加在一起,我们得到31。
31 % 26 = 5
。然后我们计算5+65=70
,这是F
的ASCII值。