首页 > 解决方案 > 我需要帮助解释这意味着什么 res += (char) ((c + key.charAt(j) - 2 * 'A') % 26 + 'A');

问题描述

public 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;
        //              (0 + A - 2 * A) % 26 + A
        
        res += (char) ((c + key.charAt(j) - 2 * 'A') % 26 + 'A');

        //System.out.println("C: "+ c +" i: "+i+ " j: "+j + " key.char: "+key.charAt(j) + " res: " + res);
        
        j = ++j % key.length();
    }
    return res;
}

我基本上只是想了解“ res += (char) ((c + key.charAt(j) - 2 * 'A') % 26 + 'A'); ”是什么意思。我几乎发现它是某种附加到字符串的?但我可以弄清楚其余部分是什么意思。

标签: java

解决方案


该方法名称错误。这不是加密。或者,如果是,它是一种 3 岁狒狒可以“解密”的加密。

char实际上是数字数据类型,因此您可以执行2*'A'. 数字是 unicode 代码。由于这显然是基于 ascii 的,并且所有 ascii 代码都直接映射到它们的 unicode 等效项而没有任何更改,您可以在网上搜索任何ascii 代码图表。例如, 'A' 只是另一种书写方式65

因此,让我们从:

c + key.charAt(j) - 2 * 'A'

java的优先规则的工作方式,2*'A'首先被解析,所以这从.中减去130 c + key.charAt(j)。如果将其视为:(c - 'A') + (key.charAt(j) - 'A'). 该公式始终产生与您所拥有的完全相同的结果,因为我只是移动了术语(我解构-2*'A'-'A'-'A'始终有效,然后移动术语)。

c是一个字符值,但由于if它前面的那个,我们确定内容在'A'(65)和'Z'(90)之间,保证。

密钥可以是任何东西(从您的粘贴中不清楚),但看起来一般的想法是密钥仅由大写字母组成,因此也是 65-90。

假设密钥是“WORLD”,要加密的文本是“HELLO”。

然后归结为:('W' - 'A') + ('H' - 'A')('W'-'A')只是计算字母表中字母 W 的“索引”。'A' 是 0 字母。B 是 1 个字母。C是2个字母。W 是 22 个字母。然后我们对这个位置的键中的字母做同样的事情......并将它们加在一起。W 是第 22 个字母,H 是第 7 个字母,所以变成29

接下来,它对%26那个起床起作用。%是余数:将 29 除以 26,折腾结果,保留余数。所以,3. (26%26 = 0, 27%26 1. 等等)。它是 26 的原因是因为字母表中有 26 个字母。如果我让你在“D”上加上“B”,你可能会告诉我:好吧,那是“E”。但是,如果我要求您将“Z”添加到“B”,那是如何工作的?好吧,我们“循环”,变成“A”。这就是% 26正在完成的事情:循环行为。

然后,我们将其添加到“A”,并将结果视为字符。3+'A'变成'D'. 这只是将索引号(5 个字母)转换回实际字母。0+'A'是A,1+'A'是B,等等。

请注意,如果键包含非大写字母(例如,如果它包含空格),此算法会做一些奇怪的事情并以负数结束。显然,这种“编码器环”级别的疯狂的作者没有考虑到这一点。

那么,这条线的意义何在?

这就是这个加密协议的工作原理:

给定一个密钥“ABC”和明文“HELLOWORLD”,我们遍历明文中的每个字母。对于每个字母,我们在键中找到匹配的字母。这里明文比密钥长,只需循环密钥即可解决。所以,'HELLOWORLD' 与 'ABCABCABCA' 匹配(为什么?就是这样j = ++j % key.length();)。

H因此,在 hello world中加密的结果是:

(/*plaintext */ 'H' + /* key */ 'A' - 'A' - 'A') % 26 + 'A'这只是H

E因此,在 hello world中加密的结果是:

(/*plaintext */ 'E' + /* key */ 'B' - 'A' - 'A') % 26 + 'A'这只是F

换句话说,如果关键字符是“C”,那么明文中的字母会通过加 2 来“加密”。D变成F。A变成C。X变成Z。然后循环;Z 变为 B。

ABC使用密钥加密文本的这种“加密”协议的结果HELLOWORLD是:HFNLPZOSND.


推荐阅读