Very new to coding, so please don't bully me.
Implement the legendary caesar cipher:
In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence.
Question: Write a function that takes a string to be encoded and a shift factor and then returns the encoded string:
caesar('A', 1) // simply shifts the letter by 1: returns 'B' the cipher should retain capitalization:
caesar('Hey', 5) // returns 'Mjd; should not shift punctuation:
caesar('Hello, World!', 5) //returns 'Mjqqt, Btwqi!' the shift should wrap around the alphabet:
caesar('Z', 1) // returns 'A' negative numbers should work as well:
caesar('Mjqqt, Btwqi!', -5) // returns 'Hello, World!'
My Solution:
function caesar(string, num) {
let arr = [];
for(let i=0;i<string.length;i++)
{if(!(/[a-zA-Z]/.test(string[i])))
{arr[i]=string[i]; continue;}
let n = string.charCodeAt(i) + num;
if (string[i] == string[i].toLowerCase())
{if(n>122)
{while(n>122)
{n-=26;}}
else
{while(n<97)
{n+=26;}
}
}
else
{if(n>90)
{while(n>90)
{n-=26;}
}
else
{while(n<65)
{n+=26;}
}
}
arr[i]=String.fromCharCode(n);
}
console.log(arr.join(''));
}
caesar("Hello, World!", 2);
caesar("Hello, World!", 75);
The code is working perfectly as per requirement, but please help me with a better solution if possible.
And if you do, please use comments to extensively explain the working process, as I'm quite the noob.
-
1\$\begingroup\$ Welcome to code review. We can't provide alternate code solutions, we do review the code and make comments. \$\endgroup\$pacmaninbw– pacmaninbw ♦2020年05月29日 00:22:59 +00:00Commented May 29, 2020 at 0:22
-
\$\begingroup\$ @pacmaninbw Okay, then. Thank you for your time. :) \$\endgroup\$Adil Ahmed– Adil Ahmed2020年05月29日 02:36:48 +00:00Commented May 29, 2020 at 2:36
1 Answer 1
Welcome to Code Review, some considerations that can help you to simplify your code:
- you have an alphabet of 26 letters, so if the shifting operation is
limited to a 26 characters range you can use the mod operation
%26
to determine the final position. - you can have a shift negative operation
num
(ex. -5), for a 26 set of elements shift this is equal to a positive shift ofMath.abs(26 - Math.abs(num))
, so for 5 the positive shift is 21.
So if you have a c
character and you want to obtain the ascii code of the corresponding shifted char of num
positions you can obtain it in the following way:
const start = c === c.toLowerCase() ? 'a'.charCodeAt(0) : 'A'.charCodeAt(0);
const diff = c.charCodeAt(0) - start;
const sh = num >= 0 ? diff + num : diff + Math.abs(26 - Math.abs(num));
const code = sh % 26 + start;
The first line returns the ascii code of 'a' or 'A' depending if the char c
is lowercase or uppercase called start
, the second gives you the difference between c
and start
, the last two lines calculate the code of the shifted corresponding character.
After your function can be rewritten in the following way:
'use strict';
function caesar(str, num) {
const arr = [];
const re = /[a-zA-Z]/;
for (const c of str) {
if (re.test(c)) {
const start = c === c.toLowerCase() ? 'a'.charCodeAt(0) : 'A'.charCodeAt(0);
const diff = c.charCodeAt(0) - start;
const sh = num >= 0 ? diff + num : diff + Math.abs(26 - Math.abs(num));
const code = sh % 26 + start;
arr.push(String.fromCharCode(code));
} else {
arr.push(c);
}
}
return arr.join('');
}
I set arr and regex
as const and instead of iterate over string using the index, I preferred the for ... of construct.
Note: I'm a javascript beginner too, so every suggestion to improve my code as for the original question is highly appreciated.
-
\$\begingroup\$ Yes yes, stupid me totally forgot about absolute value function. And yes, using ternary operator does help a lot in solidifying the code and making it more readable. Thank you for the help. Certainly appreciate it. \$\endgroup\$Adil Ahmed– Adil Ahmed2020年05月29日 12:41:08 +00:00Commented May 29, 2020 at 12:41
-
1\$\begingroup\$ @AdilAhmed You are welcome. \$\endgroup\$dariosicily– dariosicily2020年05月29日 15:42:29 +00:00Commented May 29, 2020 at 15:42
-
1\$\begingroup\$ Given you stated: "every suggestion to improve my code as for the original question is highly appreciated." Feel free to create a new question, linking to this post, and use the tag rags-to-riches \$\endgroup\$2021年02月25日 07:44:18 +00:00Commented Feb 25, 2021 at 7:44
-
\$\begingroup\$ @SᴀᴍOnᴇᴌᴀ Thank you for your suggestion and for the link, I was not aware about the
rags-to-riches
tag. \$\endgroup\$dariosicily– dariosicily2021年02月25日 08:05:36 +00:00Commented Feb 25, 2021 at 8:05 -
1\$\begingroup\$ I took your code to compare to mine in Odin project. Your code failed the large negative test included in that part of the project. The change I proposed solved it on my side. But I went quickly on it to be hones :) \$\endgroup\$FenryrMKIII– FenryrMKIII2022年10月23日 08:22:49 +00:00Commented Oct 23, 2022 at 8:22
Explore related questions
See similar questions with these tags.