-
-
Save EvanHahn/2587465 to your computer and use it in GitHub Desktop.
| /* | |
| JavaScript Caesar shift | |
| by Evan Hahn (evanhahn.com) | |
| "Encrypt" like this: | |
| caesarShift('Attack at dawn!', 12); // Returns "Mffmow mf pmiz!" | |
| And "decrypt" like this: | |
| caesarShift('Mffmow mf pmiz!', -12); // Returns "Attack at dawn!" | |
| For simplicity, only works with ASCII characters. | |
| * * * * * * * * * * * * | |
| This is free and unencumbered software released into the public domain. | |
| Anyone is free to copy, modify, publish, use, compile, sell, or distribute | |
| this software, either in source code form or as a compiled binary, for any | |
| purpose, commercial or non-commercial, and by any means. | |
| In jurisdictions that recognize copyright laws, the author or authors of this | |
| software dedicate any and all copyright interest in the software to the public | |
| domain. We make this dedication for the benefit of the public at large and to | |
| the detriment of our heirs and successors. We intend this dedication to be an | |
| overt act of relinquishment in perpetuity of all present and future rights to | |
| this software under copyright law. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
| ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| For more information, please refer to <https://unlicense.org/> | |
| */ | |
| var caesarShift = function (str, amount) { | |
| // Wrap the amount | |
| if (amount < 0) { | |
| return caesarShift(str, amount + 26); | |
| } | |
| // Make an output variable | |
| var output = ""; | |
| // Go through each character | |
| for (var i = 0; i < str.length; i++) { | |
| // Get the character we'll be appending | |
| var c = str[i]; | |
| // If it's a letter... | |
| if (c.match(/[a-z]/i)) { | |
| // Get its code | |
| var code = str.charCodeAt(i); | |
| // Uppercase letters | |
| if (code >= 65 && code <= 90) { | |
| c = String.fromCharCode(((code - 65 + amount) % 26) + 65); | |
| } | |
| // Lowercase letters | |
| else if (code >= 97 && code <= 122) { | |
| c = String.fromCharCode(((code - 97 + amount) % 26) + 97); | |
| } | |
| } | |
| // Append | |
| output += c; | |
| } | |
| // All done! | |
| return output; | |
| }; |
Or in ES:
const caesar = (text, shift) => {
return String.fromCharCode(
...text.split('').map(char => ((char.charCodeAt() - 97 + shift) % 26) + 97),
);
};I did not understood this expression
"((code - 65 + amount) % 26) + 65)" on line no 76 can you help me out.
thanks for giving me time .
There is only 26 characters in ascii, if you don't mod encrypt string by 26, encyrpted string will fall outside ascii range. for example ç => % or z = İ etc.
If you mod it by 26, encrypted string will be only ascii too, so it is guarentied it'll be human-readable. If you don't care about human readability of encrypted string, you may take it as optional.
const caesar = (text, shift) => {
return String.fromCharCode(
...text.split('').map(char => (char.charCodeAt() + shift)),
);
};
Btw, 65 and 95 is for ascii range of lowercase and uppercase characters.
@alimertcakar Good point. I've added a comment mentioning that this is ASCII-only.
I understand all of this, but why should i divide by 26? I considered manually, some garbage comes out.
I understand all of this, but why should i divide by 26? I considered manually, some garbage comes out.
I also don't understand this part
I wrote this a long time ago and don't have time to help debug this, sadly.
const caesar = (text, shift) => {
return String.fromCharCode(
...text.split('').map(char => ((char.charCodeAt() - 65 + shift) % 26) + 65),
);
};caesar("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 13) // NOPQRSTUVWXYZABCDEFGHIJKLM2020 Typescript Version:
// Caesar Cipher
const caesarCipher = (string: string, shift: number) => {
// Alphabet
const alphabet: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Encoded Text
let encodedText: string = '';
// Adjust Shift (Over 26 Characters)
if (shift > 26) {
// Assign Remainder As Shift
shift = shift % 26;
}
// Iterate Over Data
let i: number = 0;
while (i < string.length) {
// Valid Alphabet Characters
if (alphabet.indexOf(string[i]) !== -1) {
// Find Alphabet Index
const alphabetIndex: number = alphabet.indexOf((string[i]).toUpperCase());
// Alphabet Index Is In Alphabet Range
if (alphabet[alphabetIndex + shift]) {
// Append To String
encodedText += alphabet[alphabetIndex + shift];
}
// Alphabet Index Out Of Range (Adjust Alphabet By 26 Characters)
else {
// Append To String
encodedText += alphabet[alphabetIndex + shift - 26];
}
}
// Special Characters
else {
// Append To String
encodedText += string[i];
}
// Increase I
i++;
}
return encodedText;
};Example #1:
console.log(caesarCipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 2));
CDEFGHIJKLMNOPQRSTUVWXYZABExample #2:
console.log(caesarCipher('GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.', 26 + 13));
THE QUICK BROWN DOG JUMPED OVER THE LAZY FOX.Thank you! I've been struggling a lot with this exercise. Your code is wonderfully clean and instructive, I managed to get mine working thanks to you!
@mosemet, your solution works only with min characters, a more complete solution :
function shift(letter, k, code) {
return String.fromCharCode(((letter.charCodeAt() - code + k) % 26) + code);
}
function caesarCipher(s, k) {
return s.replace(/[a-z]/g, char => shift(char, k, 97)).replace(/[A-Z]/g, char => shift(char, k, 65));
}-------------------------- OR --------------------------
function isCharacterAMinLetter(char) {
return (/[a-z]/).test(char)
}
function isCharacterAMajLetter(char) {
return (/[A-Z]/).test(char)
}
function shift(letter, k, code) {
return String.fromCharCode(((letter.charCodeAt() - code + k) % 26) + code);
}
return s.replace(/[A-Za-z]/g, char => {
// check if min letter
if (isCharacterAMinLetter(char)) {
return shift(char, k, 97);
}
// check if maj letter
else if (isCharacterAMajLetter(char)) {
return shift(char, k, 65);
}
});It's working perfectly. Thanks Evan for the awesome solution!!!
function rotateAlphabet(text, noOfChars = 0){
const n = noOfChars % text.length;
return text.slice(n) + text.slice(0, n);
}
function convertText(string, noOfChars = 0) {
const alphabetLowercase = 'abcdefghijklmnopqrstuvwxyz'
const alphabetRotatedLowercase = rotateAlphabet(alphabetLowercase, noOfChars)
const alphabetUppercase = alphabetLowercase.toUpperCase()
const alphabetRotatedUppercase = rotateAlphabet(alphabetUppercase, noOfChars)
let arrayResult = []
let index = 0
for (let i = 0; i < string.length; i++) {
// if character is NOT alphanumeric
if (! /^[a-zA-Z]+$/.test(string[i])) {
arrayResult.push(string[i])
} else if (string[i] == string[i].toLowerCase()) {
// if character is lowercase
index = (alphabetLowercase.indexOf(string[i]))
arrayResult.push((alphabetRotatedLowercase[index]))
} else if (string[i] == string[i].toUpperCase()) {
// else if character is uppercase
index = (alphabetUppercase.indexOf(string[i]))
arrayResult.push((alphabetRotatedUppercase[index]))
}
}
return arrayResult.join('')
}
@mosemet, your solution works only with min characters, a more complete solution :
function shift(letter, k, code) { return String.fromCharCode(((letter.charCodeAt() - code + k) % 26) + code); } function caesarCipher(s, k) { return s.replace(/[a-z]/g, char => shift(char, k, 97)).replace(/[A-Z]/g, char => shift(char, k, 65)); }-------------------------- OR --------------------------
function isCharacterAMinLetter(char) { return (/[a-z]/).test(char) } function isCharacterAMajLetter(char) { return (/[A-Z]/).test(char) } function shift(letter, k, code) { return String.fromCharCode(((letter.charCodeAt() - code + k) % 26) + code); } return s.replace(/[A-Za-z]/g, char => { // check if min letter if (isCharacterAMinLetter(char)) { return shift(char, k, 97); } // check if maj letter else if (isCharacterAMajLetter(char)) { return shift(char, k, 65); } });
not safe to use, z will be decoded to ` instead of a

Thanks man You save me