Caesars Cipher solutions

one-line code:it work: steal from “Help me understand this one-liner for rot13 - The freeCodeCamp Forum


function rot13(a,b){return++b?String.fromCharCode((a<"["?91:123)>(a=a.charCodeAt()+13)?a:a-26):a.replace(/[a-zA-Z]/g,rot13)}
1 Like

here is mine :stuck_out_tongue:

function rot13(str) {
  const ROT1 = 'NOPQRSTUVWXYZ';
  const ROT2 = 'ABCDEFGHIJKLM';
  let newStr = "";
  var pos = 0;

  for(let i = 0; i < str.length; i++){
    if(ROT1.includes(str[i])){
      pos =  ROT1.indexOf(str[i]);
      newStr += ROT2[pos];
    } else if (ROT2.includes(str[i])){
      pos =  ROT2.indexOf(str[i]);
      newStr += ROT1[pos];
    } else {
        newStr += str[i];
    }
  }

  return newStr;
}

rot13("SERR PBQR PNZC");

1 Like

using % mod operator to short my code

const 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"];
function rot13(str) {
  let decodedStr=""
  for(let i=0;i<str.length;i++){
    if(alphabet.indexOf(str[i])>-1){
    decodedStr +=shift(str[i]);
    }else{
      decodedStr +=str[i];
    }
  }
  return decodedStr;
}
function shift(str){
  let n=(alphabet.indexOf(str)+13)%alphabet.length;
  return alphabet[n];
}
console.log(rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT."));
1 Like

Y’all, these are such good solutions! Nice one! :partying_face:

Here’s my two solutions:

With Character Chart Object

const CHARACTER_CHART = {
  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'
};

function rot13(encodedStr) {
  let decodedStr = ""
  for (let i=0; i < encodedStr.length; i++) {
    const char = encodedStr[i];
    if (CHARACTER_CHART.hasOwnProperty(char)) {
      decodedStr += CHARACTER_CHART[char];
    } else {
      decodedStr += char;
    }
  }
  return decodedStr; // Array to String
}

With character codes

const ROTATION = 13;
function rot13(str) {
  let decodedStr = "";
  for (let i = 0; i < str.length; i++) {
    const char = str[i];
    const charCode = str.charCodeAt(i);
    if (/[A-M]/.test(char)) {
      decodedStr += String.fromCharCode(charCode + ROTATION);
    } 
    else if (/[N-Z]/.test(char)) {
      decodedStr += String.fromCharCode(charCode - ROTATION);
    }
    else {
      decodedStr += char;
    }
  }
  return decodedStr;
}
3 Likes

My original version:

function rot13(str) {
  let code = "";
  let decode = "";
  let decodeStr = "";

  for (let char = 0; char < str.length; char++) {

    code = str.charCodeAt(char); // convert char to ASCII value

    // ASCII code for A is 65 and for Z it is 90
 
    if (code >= 65 && code <= 90){
      decode = code - 13;
      if (decode < 65) {
        decode = (90 - (65 - decode)) + 1; // If past A start at Z
      }
      decodeStr += String.fromCharCode(decode);
    }
    else {
      decodeStr += String.fromCharCode(code);
    }

  }
  return decodeStr;
}


console.log(rot13("SERR PBQR PNZC"));

But this version encodes and decodes by adding 13. Learned this from Asif Dawood

// Encode and Decode
function rot13(str) {
  let code = "";
  let decode = "";
  let decodeStr = "";

  for (let char = 0; char < str.length; char++) {

    code = str.charCodeAt(char);

    if (code >= 65 && code <= 90){
      decode = code + 13;
      if (decode > 90){
        decode = (65 + (decode - 90)) - 1; // If past Z start at A
      }
      decodeStr += String.fromCharCode(decode);
    }

    else {
      decodeStr += String.fromCharCode(code);
    }

  }
  return decodeStr;
}


console.log(rot13("SERR PBQR PNZC"));

console.log(rot13("FREE CODE CAMP"));
1 Like

Here’s mine:

function rot13(str) {
  const SHIFT = 13;
  const START = 'A'.charCodeAt();
  let alpha = /[a-z]/i;
  let result = '';
  
  for (let i = 0; i < str.length; i++) {
    // If the character is alphabetical 
    if (alpha.test(str[i])) {
        // Get the character code
        let charCode = str[i].charCodeAt();
        // If the character code is less than 'A', add the shift; otherwise subtract the shift
        if (charCode - SHIFT < START) {
            result += String.fromCharCode(charCode + SHIFT);
        } else {
            result += String.fromCharCode(charCode - SHIFT);
        } 
    }
    // If the character is non-alphabetical do not apply shift
    else {
        result += str[i];
    }
  }
  return result;
}

My code using regex and charcode and a variable for shift. small caps and large are allowed

function convertToCipher(str, shift) {
  let cipheredStr = "";
  for (let i = 0; i < str.length; i++) {
    if (/[A-Z]/.test(str[i])) {
      let newCapCode = str.charCodeAt(i) + shift;

      if (newCapCode > 90) {
        newCapCode = newCapCode - 26;
      }
      cipheredStr += String.fromCharCode(newCapCode);
    } else if (/[a-z]/.test(str[i])) {
      let newSmallCode = str.charCodeAt(i) + shift;

      if (newSmallCode > 122) {
        newSmallCode = newSmallCode - 26;
      }
      cipheredStr += String.fromCharCode(newSmallCode);
    } else {
      cipheredStr += str[i];
    }
  }
  return cipheredStr;
}

console.log(
  convertToCipher("Gur Dhvpx Oebja Sbk Whzcf bire gur Ynml Qbt.", 13)
);

So, here’s my solution also! :smiley:
I’ve used something called “periodic boundary condition” to manage the shift and allow both positive (encrypt) and negative (decrypt) shifts

function shiftCipher(msg, shift) {
  const 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']
  let ROTMsg="";
  const arrayMsg = msg.split("");

  for (let i=0; i<arrayMsg.length; i++){
    const char = arrayMsg[i];
    const charInAlphabet = (/[a-z]/i).test(char)
    if (charInAlphabet){
      var index = alphabet.indexOf(char);
      const signal = shift/Math.abs(shift);
      if (index+shift >= 0){
        var newIndex = (index+shift)%alphabet.length
      } 
      else {
        var newIndex = alphabet.length - (signal*(index+shift))%alphabet.length
      }
      ROTMsg += alphabet[newIndex];
    } 
    else {
      ROTMsg += char;
    }
    // Verbose / Debugging :v
    // console.log(`${char}: ${(/[a-z]/i).test(char)}. ${index} => ${(index+shift)%alphabet.length} = ${alphabet[newIndex]}. ${ROTMsg}`); 
  }
  return ROTMsg;
}

function ROT13(msg) {
  return shiftCipher(msg, 13);
}

Oh, using integers and unicode table was cool

1 Like

my solution

const rot13 = str => str.replace(/[a-z]/gi, letter => String.fromCharCode(letter.charCodeAt(0) + (letter.toLowerCase() <= ‘m’ ? 13: -13)));

this one liner will work for both upper and lowercase letters, enjoy :grinning:

% – of course! brilliant, thanks for sharing!

1 Like

Hi all,
This is my solution:

function rot13(str) {

  let decoded = "";

  // go through the string
  for (let i = 0; i < str.length; i++) {
    // check if the char is alpha
    if (str[i] >= "A" && str[i] <= "Z") {
      // transform
      let temp = String.fromCharCode(((str[i].charCodeAt(0) - 13 + 65) % 26) + 65);
      decoded += temp;
    }
    // if the char is not alpha, add it as it is
    else {
      decoded += str[i];
    }
  }
  
  return decoded;
}
1 Like

hi all, my solution:

let newValue = []
const rot13Key = 13
function rot13(str) {
const newStr = []
  str = str.toUpperCase().split("")
  for (const value of str) {
    const oldValue = value.charCodeAt(0)
    if (oldValue >= 65 && oldValue <= 77) {
      newValue = oldValue + rot13Key
    } else if (oldValue > 77 && oldValue <= 90) {
      newValue = oldValue - rot13Key
    } else {
      newValue = oldValue
    }
    newStr.push(String.fromCharCode(newValue))
    str = newStr.join("")
  }
  return str;
}
1 Like

Here is my solution.
You can give the rot13 function a second argument to shift the Alphabet , but you don’t need to.

const 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']
 
function shiftAlphabet(shift){
  let shiftedAlphabet=[...alphabet]
  for(let i=shift; i >0; i--){
    shiftedAlphabet.push(shiftedAlphabet.shift());
     }
   return shiftedAlphabet;
 }


 function replaceLetter(string,shift){

   let index=alphabet.indexOf(string)
    return shiftAlphabet(shift)[index]
 }
 
 function rot13(str,shift=13) {
   let returnArray=[]
   
   for (const letter of str) {
    returnArray.push(letter.replace(/[A-Z]/,replaceLetter(letter,shift)));
  }
   return returnArray.join("");
 }
console.log(rot13("FREE CODE CAMP",8))
//encode with every value
console.log(rot13("NZMM KWLM KIUX",18))
//decode with (26-encode value)

rot13("SERR PBQR PNZC");
1 Like

Here is my solution :slight_smile:

function rot13(str) {
  // Define return variable
  let ans = "";

  // Get length of string
  let length = str.length;

  // Loop through each of the characters in the string
  for (let i = 0; i < length; i++) {
    // If character is a letter, apply cipher
    if (/[A-Z]/.test(str[i])) {
      ans += cipher(str[i]);
    }
    // If character is not a letter, retain
    else {
      ans += str[i];
    }
  }

  // Return encoded string
  return ans;
}

// Define function that applies the cipher to a character
const cipher = (char) => {
    // Convert character to ASCII and add 13
    let ascii = char.charCodeAt() + 13;
    // If ASCII exceeds 'Z', go back to 'A'
    if (ascii > 90) {
        ascii = 65 + (ascii - 90) - 1;
    }
    // Convert ASCII back to character and return it
    return String.fromCharCode(ascii);
}

you are welcome :smiley: :smiley:
yeah I like the idea of using %
still wonder why it doesn’t work while we were live streaming

Hey guys. Find my simple solution here:

function rot13(str) {

  let alphabets = ['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','A','B','C','D','E','F','G','H','I','J','K','L','M'];
  let result = '';
  for (let i = 0; i < str.length; i++){
    if (str[i] === '?'| str[i] ==='.'| str[i] ==='!'| str[i] === ' '){
        result = result.concat('', str[i]);  
          } 
    for(let j = 0; j < 26; j++){ 
          if(str[i] === alphabets[j]){
      result = result.concat((alphabets[(13 + alphabets.indexOf(alphabets[j]))]));
      
      }   
    }
  }
  return result;
  
  
}

console.log(rot13("SERR PBQR PNZC"));
console.log(rot13("SERR YBIR?"));
console.log(rot13("SERR CVMMN!"));

interesting solution Omar, I’m in awe!

This solution is the closest to everyday English I have seen for this particular algorithm. I’ll copy it, thanks.

Hello guys,

Here’s my not so elegant solution :joy:

(almost no brain cells were harmed in the making of this solution)

Solution #1

const CIPHER = {
     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'
  };

function rot13(str) {
  let decoded = "";

  for(let i = 0; i < str.length; i++){
    if(CIPHER.hasOwnProperty(str[i]) === true){
      decoded += (CIPHER[str[i]]);
    }
    else if(CIPHER.hasOwnProperty(str[i]) === false){
      decoded += (str[i]);
    }
  }
  return decoded;
}
console.log(rot13("SERR. PBQR. PNZC?!"));

(Edit: Brushed up my original solution a bit after watching the video :laughing:)

After watching, I realized that my solution is not dynamic/flexible as it only works exclusively for ROT13. So I tried doing the project again. This time I can set the amount of shifting or rotation from 1 to 13.

(RIP brain cells)

Solution #2

const ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // alphabet - 26 letters

function rot13(str){
  let decoded = ""; // storage for decoded string
  let newLetter = ""; // storage for the new/decoded letter based from its new index
  let newIndex; // storage for the new index based on the number of shifts
  let shift = 13; // the number of shift (applicable only from 1-13) 
  let maxShift = shift*2; // maximum index value a new/decoded letter can have

  for(let i = 0; i < str.length; i++){ // for loop to access every letter in the given string
    if(ALPHA.includes(str[i]) === true){ // if a letter in the given string is present at ALPHA (line 2)
        newIndex = ALPHA.indexOf(str[i]) + shift; // then the letter should move *shift* places
      if(newIndex < maxShift){ // if the new index of the new letter (line 13) is < maxShift (line 9)
        newLetter = ALPHA[newIndex]; // then store the new letter in the variable newLetter
        decoded += newLetter; // and then store newLetter to decoded variable
      }
      else if(newIndex >= maxShift){ // but if new index of the new letter (line 13) is >= maxShift (line 9)
        newIndex -= maxShift; // then subtract the new index of the new letter by maxShift (line 9)
        newLetter = ALPHA[newIndex]; // and then store the new/decoded letter based on its new index in the variable newLetter
        decoded += newLetter; // and then store newLetter to decoded variable
      }
    }
    else if(ALPHA.includes(str[i]) === false){ // if a letter in the given string is not present at ALPHA (line 2)
      decoded += str[i]; // then just store it to decoded variable 
    }
  }
  return decoded; // after looping, return the value of decoded variable out of the function 
};
console.log(rot13("SERR. PBQR. PNZC?!"));

Since I have the luxury of time and wanted to be extra, I tried to enable the number of rotations from 14 to 26 too like the one on this website

I realized after doing this I could have used charCodeAt() :woman_facepalming: But whatever. I like beating myself up with math problems anyway :joy:

(yep, I just love math)

Solution #3

const ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

function rot13(str){
  let upperStr = str.toUpperCase();
  let decoded = ""; 
  let newLetter = ""; 
  let newIndex; 
  let rot = 13; 
  let maxIndex = 25 - rot; 

  for(let i = 0; i < upperStr.length; i++){
    if(ALPHA.includes(upperStr[i]) === true){
      if(ALPHA.indexOf(upperStr[i]) <= maxIndex){
        newIndex = ALPHA.indexOf(upperStr[i]) + rot;
        newLetter = ALPHA[newIndex];
        decoded += newLetter;
      }
      else if(ALPHA.indexOf(upperStr[i]) > maxIndex){
        newIndex = ALPHA.indexOf(upperStr[i]) - maxIndex - 1;
        newLetter = ALPHA[newIndex];
        decoded += newLetter;
      }
    }
    else if(ALPHA.includes(upperStr[i]) === false){ 
      decoded += upperStr[i];
    }
  }  
  return decoded;
};
console.log(rot13("abcdefghijklmnopqrstuvwxyz !?"))
1 Like