对 Java 中的 Vigenère 密码实现感到困惑
Confused about Vigenère cipher implementation in Java
请有人解释下面突出显示的代码行。我完全不明白这条线是如何工作的。
你可以用这个例子来帮助我:
输入:攻击
关键词:柠檬
水库: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;
}
背景
该代码使用字母的 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
的便捷方式。
现在我们有一个从零开始的值,但可能大于 25。因此我们对它取模:
(c + key.charAt(j) - 2 * 'A') % 26
然后我们需要将 65 添加回该值,以将其带回 ASCII 的 A-Z 范围:
(c + key.charAt(j) - 2 * 'A') % 26 + 'A'
唯一剩下的步骤是将其转换为 char
,因为默认情况下结果是 int
:
res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
例子
如果输入是ATTACK
并且关键字是LEMON
,那么在某些时候我们将不得不考虑输入字母T
(ASCII 84)和关键字字母 M
(ASCII 77).
从每个减去 65,我们有 T=19 和 M=12。加在一起,我们得到 31。
31 % 26 = 5
。所以我们然后计算 5+65=70
,这是 F
.
的 ASCII 值
请有人解释下面突出显示的代码行。我完全不明白这条线是如何工作的。
你可以用这个例子来帮助我:
输入:攻击 关键词:柠檬 水库: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;
}
背景
该代码使用字母的 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
的便捷方式。
现在我们有一个从零开始的值,但可能大于 25。因此我们对它取模:
(c + key.charAt(j) - 2 * 'A') % 26
然后我们需要将 65 添加回该值,以将其带回 ASCII 的 A-Z 范围:
(c + key.charAt(j) - 2 * 'A') % 26 + 'A'
唯一剩下的步骤是将其转换为 char
,因为默认情况下结果是 int
:
res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
例子
如果输入是ATTACK
并且关键字是LEMON
,那么在某些时候我们将不得不考虑输入字母T
(ASCII 84)和关键字字母 M
(ASCII 77).
从每个减去 65,我们有 T=19 和 M=12。加在一起,我们得到 31。
31 % 26 = 5
。所以我们然后计算 5+65=70
,这是 F
.