[英]Caesar Cipher in javascript: cipher broken
I'm building a Caesar Cipher in javascript.我正在用 javascript 构建一个凯撒密码。 It uses a randomly set variable called
currentkey
as the cipher's key.它使用一个随机设置的变量
currentkey
作为密码的密钥。 it can be a number from -25 to +25, skipping 0.它可以是从 -25 到 +25 的数字,跳过 0。
I can't figure out why the function returns undefined in the beginning of the string, or why it translates the same letter for as long as the string goes, or even why that letter doesn't get translated at all.我不明白为什么函数在字符串的开头返回 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;
}
For example, running convertKey("example")
returns undefinedeeeeeee
(undefined + 7 times the first letter in "example").例如,运行
convertKey("example")
返回undefinedeeeeeee
(未定义 + "example" 中第一个字母的 7 倍)。
Implementation the Caesar Cipher algorithm in JavaScript is very interesting due to the fact that JavaScripts lacks true modulo operator.由于 JavaScript 缺少真正的模运算符,因此在 JavaScript 中实现 Caesar Cipher 算法非常有趣。 The % is just the reminder of division.
% 只是除法的提醒。 Read this article for more explanations.
阅读这篇文章以获得更多解释。
However, you can easily define the modulo as a custom function and then proceed to the implementation of the Caesar Cipher - which is a very simple form of encryption, in which each letter in the original message is shifted to the left or right by a certain number of positions.但是,您可以轻松地将模定义为自定义函数,然后继续实现凯撒密码——这是一种非常简单的加密形式,其中原始消息中的每个字母向左或向右移动某个职位数。
To decrypt the message we simply shift back the letters the same number of positions.要解密消息,我们只需将字母移回相同数量的位置。
Example:例子:
If after shifting a letter goes outside the range of letters, then the letter is wrapped around in alphabet.如果移位后一个字母超出了字母范围,则该字母将在字母表中环绕。 Example: Letter Z becomes C if is shifted by 3 positions.
示例:如果字母 Z 移动 3 个位置,则变为 C。
This “wrap-around” effect means use of modulo.这种“环绕”效果意味着使用模数。 In mathematical terms, the above can be expressed as this:
用数学术语来说,上面的可以表示为:
En(x) = (x + n) mod 26 En(x) = (x + n) mod 26
Dn(x) = (x – n) mod 26 Dn(x) = (x – n) mod 26
Trying to implement this algorithm in JavaScript without the use of a proper modulo operator will produce either incorrect results or a very cryptic and difficult to understand code.在不使用适当的模运算符的情况下尝试在 JavaScript 中实现此算法将产生不正确的结果或非常神秘且难以理解的代码。
By using a custom modulo function, the code expresses the mathematical equation identically:通过使用自定义模函数,代码以相同的方式表达数学方程:
// 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;
}
Have fun!玩得开心!
Encrypt a few messages to try out the code.加密一些消息以试用代码。 Remember: If you encrypt with a positive key, use the complementary negative key to decrypt it.
请记住:如果您使用正密钥进行加密,请使用互补的负密钥对其进行解密。 You can also use this code to decode those ROT13 messages that appears everywhere on the web and newsgroups.
您还可以使用此代码来解码出现在网络和新闻组中随处可见的 ROT13 消息。
If you want to find out other ways of implementing modulo in JavaScript, please consult the article mentioned at the beginning of this post.如果您想了解在 JavaScript 中实现取模的其他方法,请参阅本文开头提到的文章。
(1) You are not iterating through your array o_letters
properly. (1) 您没有正确地遍历数组
o_letters
。
(2) You are going out-of-bounds for your array. (2) 你的数组越界了。
for (var i = 0; i < o_letters.length; i++) {
_x = alphabet[(alphabet.indexOf(o_letters[i]) + currentkey + 26) % 26]
c_text = c_text + _x;
}
Also, in your code, you don't need .split("")
at all.此外,在您的代码中,您根本不需要
.split("")
。
I would just do this:我只会这样做:
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;
}
Or more succinctly (but less efficiently):或者更简洁(但效率较低):
function convertKey(str) {
return str.split('').map(function(c) {
return String.fromCharCode((c.charCodeAt(0) + currentKey + 26) % 26);
}).join('');
}
The undefined
is a result of not initializing c_text
before you try concatenate it with _x
. undefined
是在尝试将c_text
与_x
连接之前未初始化的结果。
The code only works on one letter because alphabet.indexOf(x)
returns -1
(not found).该代码仅适用于一个字母,因为
alphabet.indexOf(x)
返回-1
(未找到)。 When using o_text = "abc"
, x
equals 0, 1, and 2. Thus, the index of 0, 1, or 2 in alphabet
is nonexistent (indicated by the -1
result).使用
o_text = "abc"
, x
等于 0、1 和 2。因此, alphabet
的 0、1 或 2 索引不存在(由-1
结果指示)。 You need to relate those numbers back to o_text
by changing indexOf(x)
to indexOf(o_text[x])
.您需要通过将
indexOf(x)
更改为indexOf(o_text[x])
将这些数字关联回o_text
。 Also, to prevent going outside the bounds of your array, you need a modulus operation to wrap values greater than 26 (I've used alphabet.length
to allow this code to work with other alphabets) back around into a valid region.此外,为了防止超出数组的范围,您需要一个模数运算来将大于 26 的值(我使用了
alphabet.length
长度以允许此代码与其他字母表一起使用)回绕到有效区域。 Thus, the correct code would be as follows (note: I've moved 'w' in your array into its proper location alphabetically, as I assumed its location in your example was an error and not intentional):因此,正确的代码如下(注意:我已将数组中的 'w' 按字母顺序移动到其正确位置,因为我假设它在您的示例中的位置是错误而不是故意的):
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'));
This alert's fghijklmnopqrstuvwxyzabcde
此警报的
fghijklmnopqrstuvwxyzabcde
// working at https://www.freecodecamp.org/challenges/caesars-cipher // 在https://www.freecodecamp.org/challenges/caesars-cipher工作
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.");
Here's a more simple answer:这是一个更简单的答案:
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(''); }
function rot13(str) {
const alphabet1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXY';
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
return str
.split('')
.map(function(char) {
const pos = alphabet.indexOf(char);
return pos >=0? alphabet1[pos+13] : char;
})
.join('');
}
rot13("SERR PBQR PNZC");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.