加密混淆了Vigenère密码在Java中的实现
请有人解释一下下面突出显示的代码行。我完全不明白这条线是怎么运作的
你可以用这个例子来帮助我:
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;
}
# 1 楼答案
背景
代码使用字母的ASCII值。字母A-Z是ASCII值65-90
其想法是将两个字母相加,但如果值超过90(称为modular arithmetic),则将其环绕。所以91应该是65(即^{)
Java提供了一个)
%
操作符来进行模运算(x % n
)。然而,这是为了处理一系列数字0→n-1。所以,如果我们从每个字母中减去65,我们就在0的范围内工作→25.这允许我们使用模运算符(^{这就是代码所做的:
这一部分将这两个字母相加,但也从每个字母中减去65。如果写为以下内容,可能更容易理解:
你会注意到你可以用
- 'A'
作为一种方便的方式来做- 65
现在我们有一个基于零的值,但可能大于25。然后我们将其模化:
然后我们需要将65加回到该值,使其回到ASCII的A-Z范围:
剩下的唯一一步是将其强制转换为
char
,因为默认情况下,结果是int
:范例
如果输入是^ {< CD9>},关键字是^ {CD10>},那么在某个时候,我们必须考虑输入字母^ {< CD11>}(ASCII 84)和关键字母^ {CD12>}(ASCII 77)。p>
减去65,我们得到T=19和M=12。加起来,我们得到31个
31 % 26 = 5
。然后我们计算5+65=70
,这是F
的ASCII值