我是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");
答案 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,我们只需再次应用它来获取原始数据。
那么,算法如何运作:
正如已经指出的那样,我们对大写字母A-Z的字符代码在65(A)到90(Z)的范围内。但我们希望使用模运算来查找新字母的范围为0-26。所以从目标字母的字符代码中减去65: str [x] .charCodeAt() - 65
应用密码:添加13
(str [x] .charCodeAt() - 65 + 13)
应用模数找到已经循环播放的字母'周围。对我们来说,这是%26(字母表中的字符数):
(str [x] .charCodeAt() - 65 + 13)%26
加回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
来源(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)