0

我是 javascript 新手,这是 Basic Algorithm Scripting 的最后一门课程。我正在尝试理解这行代码,因为我从免费代码营获得前端开发证书的下一部分,我想了解一切。我一直在寻找解决方案并找到了这个。我理解评论中的一些内容,但我很难理解公式,这段代码 100% 有效,但我只需要进一步理解。这是代码:

function rot13(str) {

  //retCharArray is an Array of character codes for the solution
  var rotCharArray = [];

  //regular expression for all upper case letter from A to Z
  var regEx = /[A-Z]/;

  //split str into a character array
  str = str.split("");

  for (var x in str) { //iterate over each character in the array
    //regEx.test(str[x]) will return (true or false) if it maches the regEx or not
    if (regEx.test(str[x])) {
      // A more general approach
      // possible because of modular arithmetic 
      // and cyclic nature of rot13 transform

      // I DON'T CLEARLY UNDERSTAND THIS CODE BELOW
      rotCharArray.push((str[x].charCodeAt() - 65 + 13) % 26 + 65);
    } else {
      rotCharArray.push(str[x].charCodeAt());
    }
  }
  //make a string with character codes from an array of character codes
  str = String.fromCharCode.apply(String, rotCharArray);
  return str;
}

// Change the inputs below to test
rot13("SDASasd");

4

3 回答 3

3

上面的两个答案在这里回答了您的问题的一半,但他们并没有真正看到您的问题,即要回答 Free Code Camp 挑战,您必须了解凯撒密码和 ROT13 算法背后的数学。我也有这个问题。

让我们一起来看看,一步一步地过一遍。(我明白并不是每个人都在高中学习过这个 - 我没有!):

  // I DON'T CLEARLY UNDERSTAND THIS CODE BELOW
  rotCharArray.push((str[x].charCodeAt() - 65 + 13) % 26 + 65);
} else {
  rotCharArray.push(str[x].charCodeAt());
}

@bastos.sergio 和 @caulitomaz 的答案都有帮助,但它们只是部分解释,并不指向您进一步研究:

@bastos.sergio 的

"获取 26 的模数(这样可以确保编码不会加密到 'Z' 字母之上的任何内容,例如 'Z' 字母将转换为 (90-65+13) % 26 + 65) = 77 'M ' 信。本质上,它将使加密算法循环到开头。

@caulitomaz 的

在英文字母表中有26个字符。这就是为什么您应用 13 的密码轮换然后应用模运算的原因。

他们在这里都指的是“模块化算术”:

模算术表明某些数字是“全等的”,也就是说,当对它们应用模运算时,它们共享相同的余数。

例如,2 % 12, 14 % 12, 26 % 12 = 余数 2。这样,当您的数字必须出现在某个范围内,或者设备只显示某个范围内的数字时,您可以计算出数字'循环回来'。

请注意,在我的示例中,使用了 % 12 - 这是 12 小时制时钟可以显示的总小时数。所以如果是凌晨 2 点,我想知道 12 小时后的时间,我加 12。但我的时钟不能显示 14:00(不是 12 小时模式)。模 12 给了我实时。

示例: 现在是凌晨 4 点。我的飞机延误了 29 小时(这是一家糟糕的航空公司)。我如何计算新的起飞时间?4 + 29 % 12 = 上午 9 点。(如果延迟小于 24,我需要交换 am/pm,但你应该得到图片。)

ROT13

在这里,我们有一个特殊的旋转密码 ROT 13 的情况,其中应用两次密码将为您提供要编码的原始字符,因为字母表只有 26 个字符,而 13 正好是 26 的一半。

x = ROT13(ROT13(x))

所以实际上,在应用或反转加密时,我们不需要担心加 13 或减 13,我们只需再次应用它即可得到原来的。

那么,算法是如何工作的

  1. 正如已经指出的,我们的大写 AZ 字符代码在 65 (A) 到 90 (Z) 的范围内。但是我们想使用模运算来找出新字母在 0-26 范围内的位置。所以从目标字母的字符代码中减去 65:str[x].charCodeAt() - 65

  2. 应用密码:加 13

    (str[x].charCodeAt() - 65 + 13)

  3. 应用模数来找到“循环”的字母。对我们来说是 % 26(字母表中的字符数):

    (str[x].charCodeAt() - 65 + 13) % 26

  4. 加回 65,这样我们就有了 65...90 范围内的字符代码

    (str[x].charCodeAt() - 65 + 13) % 26 + 65)

工作示例:

ROT13(X)

'X'.charCodeAt(0) = 88

- 65 = 23 

+ 13 = 36

%26 = 10 

+65 = 75 

charCodeFrom(75) = K

ROT13(K)

'K'.charCodateAt(0) = 75

- 65 = 10

+ 13 = 23

%26 = 23

+65 = 88

charCodeFrom(88) = X

来源:

http://betterexplained.com/articles/fun-with-modular-arithmetic/ https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/what-is-modular-arithmetic

于 2016-05-01T09:22:08.740 回答
1

由于您只使用大写字符,因此您需要了解您正在使用的字符代码范围。大写“A”对应于 65。

'A'.charCodeAt(0)返回65

你的最大值是'Z',它对应于90

在英文字母表中有26个字符。这就是为什么您应用 13 的密码轮换然后应用模运算的原因。

要检索正确的 charCode,将再次将 65 添加到结果中。

rotCharArray.push((str[x].charCodeAt() - 65 + 13) % 26 + 65);

于 2016-04-29T16:28:24.910 回答
0

第一的。该代码仅转换大写字母(查看下面的 ascii 表)

(str[x].charCodeAt() - 65 + 13) % 26 + 65

这转化为,

  1. 获取 charcode 编号(它将在 65 和 90 之间)减去 65
  2. 添加 13
  3. 获取 26 的模数(这确保编码不会加密到 'Z' 字母之上的任何内容,例如 'Z' 字母将转换为 (90-65+13) % 26 + 65) = 77'M' 字母。本质上,它将使加密算法循环到开头.
  4. 加回 65

ASCII 表

于 2016-04-29T16:45:06.683 回答