来自.charCodeAt()的ROT13密码?

时间:2016-04-29 15:55:00

标签: javascript char fromcharcode

我是javascript的新手,这是Basic Algorithm Scripting的最后一个课程。我试图理解这行代码,因为我从免费代码阵营获得前端开发证书的下一部分,我想了解eveything我一直在寻找解决方案并找到了这个。我理解评论中的一些内容,但我很难理解公式,这段代码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");

3 个答案:

答案 0 :(得分:2)

上面的两个答案在这里回答了你的问题的一半,但他们并没有真正看到你的问题,即回答免费代码训练营的挑战,你必须要去了解凯撒密码背后的数学和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' S

  

英文字母中有26个字符。这就是你申请的原因   cypher旋转13然后应用模运算。

他们在这里指的是" 模块化算术":

模块化算术表明某些数字是' 全等',即当对它们应用模运算时,它们共享相同的余数。

例如,2%12,14%12,26%12 =余数2.这样,当您有一个必须出现在某个范围内的数字,或者只显示某个范围内的数字的设备时,您就可以工作了这个数字在哪里循环回来'。

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

示例: 凌晨4点。我的飞机已被推迟了29个小时(这是一个可怕的航空公司)。我如何计算新的起飞时间? 4 + 29%12 =上午9点。 (如果延迟小于24,我需要交换上午/下午,但你应该得到图片。)

ROT13

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

  

x = ROT13(ROT13(x))

实际上,在应用或撤消加密时,我们不需要担心增加13或减去13,我们只需再次应用它来获取原始数据。

那么,算法如何运作

  1. 正如已经指出的那样,我们对大写字母A-Z的字符代码在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)

  5. 工作示例:

    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
    

    来源(S):

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

答案 1 :(得分:1)

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

'A'.charCodeAt(0)返回65

您的最大值为'Z',对应90

英文字母中有26个字符。这就是为什么你应用cypher旋转13然后应用模运算。

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

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

答案 2 :(得分: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
  5. ASCII table