我正在用javascript构建一个Caesar Cipher。它使用一个名为currentkey
的随机设置变量作为密码的密钥。它可以是-25到+25之间的数字,跳过0。
我无法弄清楚为什么函数在字符串的开头返回undefined,或者为什么它只要字符串转换就转换相同的字母,或者甚至为什么那个字母根本没有被翻译。
var currentkey = 5 //for example
function convertKey(str) {
var o_text = str;
var o_letters = o_text.split("");
var alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','w','z']
var c_text, _x = "";
for (x in o_letters) {
if (currentkey > 0) {
_x = alphabet[alphabet.indexOf(x) + currentkey]
} else {
_x = alphabet[alphabet.indexOf(x) + (26 - currentkey)]
}
c_text = c_text + _x;
}
return c_text;
}
例如,运行convertKey("example")
会返回undefinedeeeeeee
(未定义+“示例”中第一个字母的7倍)。
undefined
是在尝试将c_text
与_x
连接之前不初始化alphabet.indexOf(x)
的结果。
该代码仅适用于一个字母,因为-1
返回o_text = "abc"
(未找到)。当使用x
时,alphabet
等于0,1和2.因此,-1
中的0,1或2的索引是不存在的(由o_text
结果表示)。你需要通过将indexOf(x)
更改为indexOf(o_text[x])
将这些数字与alphabet.length
联系起来。另外,为了防止超出数组的范围,您需要一个模数运算来将大于26的值(我使用var currentkey = 5 //for example
function convertKey(str) {
var o_text = str;
var o_letters = o_text.split("");
var alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
var c_text="", _x = "";
for (x in o_letters) {
if (currentkey > 0) {
_x = alphabet[(alphabet.indexOf(o_letters[x]) + currentkey) % alphabet.length]
} else {
_x = alphabet[(alphabet.indexOf(o_letters[x]) + (26 - currentkey)) % alphabet.length]
}
c_text = c_text + _x;
}
return c_text;
}
alert(convertKey('abcdefghijklmnopqrstuvwxyz'));
以允许此代码与其他字母表一起使用)包装回有效区域。因此,正确的代码如下(注意:我已经按字母顺序将数组中的'w'移动到其正确的位置,因为我假设它在您的示例中的位置是错误而不是故意的):
fghijklmnopqrstuvwxyzabcde
这个警报是o_letters
(1)你没有正确地遍历你的数组for (var i = 0; i < o_letters.length; i++) {
_x = alphabet[(alphabet.indexOf(o_letters[i]) + currentkey + 26) % 26]
c_text = c_text + _x;
}
。
(2)你的阵列越界越界。
.split("")
此外,在您的代码中,您根本不需要var currentkey = 5 //for example
function convertKey(str) {
var ret = '';
for (var i = 0; i < str.length; i++) {
ret += String.fromCharCode((str.charCodeAt(i) + currentKey + 26) % 26);
}
return ret;
}
。
我会这样做:
function convertKey(str) {
return str.split('').map(function(c) {
return String.fromCharCode((c.charCodeAt(0) + currentKey + 26) % 26);
}).join('');
}
或者更简洁(但效率更低):
article
由于JavaScripts缺少真正的模运算符,因此在JavaScript中实现Caesar Cipher算法非常有趣。 %只是分裂的提醒。阅读此// Function will implement Caesar Cipher to
// encrypt / decrypt the msg by shifting the letters
// of the message acording to the key
function encrypt(msg, key)
{
var encMsg = "";
for(var i = 0; i < msg.length; i++)
{
var code = msg.charCodeAt(i);
// Encrypt only letters in 'A' ... 'Z' interval
if (code >= 65 && code <= 65 + 26 - 1)
{
code -= 65;
code = mod(code + key, 26);
code += 65;
}
encMsg += String.fromCharCode(code);
}
return encMsg;
}
// Implement modulo by replacing the negative operand
// with an equivalent positive operand that has the same wrap-around effect
function mod(n, p)
{
if ( n < 0 )
n = p - Math.abs(n) % p;
return n % p;
}
以获取更多解释。
但是,您可以轻松地将模数定义为自定义函数,然后继续执行Caesar Cipher - 这是一种非常简单的加密形式,其中原始消息中的每个字母都向左或向右移动一定的职位数量。
为了解密消息,我们只需将字母移回相同数量的位置。
例:
如果在移动一个字母超出字母范围之后,则该字母将以字母顺序包裹。示例:如果移位3个位置,则字母Z变为C.
这种“环绕”效应意味着使用模数。在数学术语中,上述可以表示为:
一(x)=(x + n)对26
Dn(x)=(x - n)与26
尝试在JavaScript中实现此算法而不使用正确的模运算符将产生不正确的结果或非常神秘且难以理解的代码。
通过使用自定义模数函数,代码表达相同的数学方程式:
https://www.freecodecamp.org/challenges/caesars-cipher
玩得开心!
加密一些消息以试用代码。请记住:如果使用正键加密,请使用互补的否定密钥对其进行解密。您还可以使用此代码解码出现在Web和新闻组中的任何位置的ROT13消息。
如果您想了解在JavaScript中实现modulo的其他方法,请参阅本文开头提到的文章。
//在function rot13(str){
var res = [];
var currentPosition;
var shiftedPosition;
for (var i = 0; i<str.length; i++){
currentPosition = str.charCodeAt(i);
if (currentPosition<65 || currentPosition>90){
res.push(String.fromCharCode(currentPosition));
}
shiftedPosition = str.charCodeAt(i) - 13;
if (currentPosition>=65 && shiftedPosition <65){
res.push(String.fromCharCode(91-(13-(currentPosition-65))));
}
if (currentPosition>=78 && currentPosition<=90){
res.push(String.fromCharCode(shiftedPosition));
}
}
return res.join('');`enter code here`
}
// Change the inputs below to test
rot13("GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.");
工作
var rot = {
'A': 'N',
'B': 'O',
'C': 'P',
'D': 'Q',
'E': 'R',
'F': 'S',
'G': 'T',
'H': 'U',
'I': 'V',
'J': 'W',
'K': 'X',
"L": 'Y',
'M': 'Z',
'N': 'A',
'O': 'B',
'P': 'C',
'Q': 'D',
'R': 'E',
'S': 'F',
'T': 'G',
'U': 'H',
'V': 'I',
'W': 'J',
'X': 'K',
'Y': 'L',
'Z': 'M',
' ': ' ',
'.': '.',
'!': '!',
'?': '?'
};
// Change the inputs below to test
rot13("SERR CVMMN!");
// FREE CODE CAMP
function rot13(str) {
var index = [];
for (var key in str) {
for (var property in rot) {
if (str[key] === property) {
index.push(rot[property]);
}
}
}
return index.join('');
}
这是一个更简单的答案:
qazxswpoi