Caesars Cipher - transforming index value to character representation

Hi,

I am working on the Caesars Cipher project. I have gotten to the point where I am able to take a encrypted character and use it to find its index in the alphabet and add or subtract by 13 places respectively.

The problem:

I am then trying to to transform the index back to its character representation in the sequence using the alphabet variable just before I push to the new array, but I am not sure how to.

function isSpecial(character) {
  let regex = /[^A-Za-z0-9]+/gi;
  return regex.test(character);
} 

function rot13(str) {
  let encryptedText = str.split("");
  let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  let decodedText = [];
  
  for (let i = 0; i < encryptedText.length; i++) {
    // Check for special characters.
    if (isSpecial(encryptedText[i])) {
       decodedText.push(encryptedText[i]);
    } else {

      if (alphabet.indexOf(encryptedText[i]) >= 13) {
        // subtract by 13 places.
         decodedText.push(alphabet.indexOf(encryptedText[i])-13);
      } else {
      // add by 13 places.
        decodedText.push(alphabet.indexOf(encryptedText[i])+13);
      }
    }
  }
  return decodedText.join("");
}


let result = rot13("SERR PBQR PNZC"); // 51744 21434 201215
console.log(result);


Thanks.

So you’re actually really close. One pointer to steer you toward your answer, and one question to think about.

First, the guidance. You’re using alphabet.indexOf() to find the index of a given character in the alphabet string. If the letter was F, the indexOf would be 5, because alphabet[5]==="F". So you add or subtract 13 from that index… But does the index still refer to a value in the array (the alphabet string)? Looking in this paragraph, you might see something more useful to push than the index value.

And now, a question. In the context of the cipher, what are you converting? Everything else should be a “special character”, right? So why is your regex also looking for numbers?

Thank you for your feedback.

I would like to address your question first and I am glad you brought it up. After doing some extra research on the match() method, I had overlooked that this method is only used on string values and any numerical values need to be converted using .toString() and is why numbers were not being checked against the regex.

Apologies if I am wrong but the regex is finding all non-alphanumeric characters in the brackets by declaring ^ at the beginning of the regex. I updated my code above which only special characters return true, letters and numbers return false.

In regards to my problem:

  • I considered using a nested for loop for the alphabet, but I don’t believe that is the correct approach.

  • Next I considered String.fromCharCode() and .charCodeAt() but I am not dealing with the ASCII table.

  • I am not sure if .charAt() could be useful or I might not be using it in the correct manner.

I am able to add and subtract from the index. I am still not sure how to solve this and its probably staring me in the face. I am trying to be careful when I research as I wouldn’t like to stumbled across the full solution.

Thanks.

Why not so exactly as you’re doing, but push alphabet[index plus-or-minus 13] instead of pushing the index value itself?

And the point to my question was, you aren’t encoding numbers. Your regex should check for alpha but for this, numeric values should be ignored.

I finally did it!

I had been working on this project since Monday or Tuesday. There were several occasions where I almost ruined the challenge by looking at solutions. However, this wasn’t the case and I persevered and referred to MDN and W3School when needed.

In order to retrieve the decoded string, I took each encoded character and retrieved its index from the alphabet, and shifted the index by 13 positions, I then stored the index in a variable just for simplicity. Then pushed the letter from the alphabet using the alphabet position.

function isSpecial(character) {
  let regex = /[^A-Za-z0-9]+/gi;
  return regex.test(character);
} 

function rot13(str) {
  let encryptedText = str.split("");
  let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  let decodedText = [];
  let alphabetPosition = 0;
  for (let i = 0; i < encryptedText.length; i++) {
    // Check for special characters.
    if (isSpecial(encryptedText[i])) {
       decodedText.push(encryptedText[i]);
    } else {
      if (alphabet.indexOf(encryptedText[i]) >= 13) {
        // subtract by 13 places.
         alphabetPosition = alphabet.indexOf(encryptedText[i])-13;
         decodedText.push(alphabet[alphabetPosition])
      } else {
         // add by 13 places.
         alphabetPosition = alphabet.indexOf(encryptedText[i])+13;
         decodedText.push(alphabet[alphabetPosition])
      }
    }
  }
  return decodedText.join("");
}


let result = rot13("SERR PBQR PNZC"); // 51744 21434 201215
console.log(result);

I had solved caesars cipher previously in PHP but I was encoding instead of decoding and I refused to look at the solution.

Thank you for the guidance.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.