Ceaser Cipher Toy Problem Walkthrough
Published: 2019-12-18 23:05:37

In cryptography, the Ceasar cipher is a shift cipher. It is a simple encryption technique that is named after Julius Ceaser who used the cipher to communicate with his generals. The concept behind a Ceaser cipher is that it is still a message written in plain text but every letter is shifted down the alphabet by a chosen number. While at first sight, this is an effective way to encrypt a message Ceaser ciphers are fairly easy to break. All it takes is to find the encryption method is looking for commonly used words and letter patterns. Once you crack one word of the code the rest falls into place.

Say our message is "Marsupials are the future" let's make our offset 6 meaning every character will be shifted down the alphabet 6 letters. The encoded message would then be "Sgxyavogry gxk znk lazaxk". 

In order to make our cipher more secure, we are going to change up the alphabet available this will make the pattern a little less predictable to the code breakers waiting around every corner. 
If we were to use the same message and encode it with the alphabet "mfutrip" the new message would be "patsfirals ate uhe mfufte".



Alright, let's get down to some code.
first let's start off with a shell of a function and some variables to work with. 

```
const ceasarCipher = (options) => {
  let { alphabet, offset, message, command } = options;
}
```

Now let's decide our IOCE:
Inputs: 
In this Ceasar cipher, we are using the following parameters,
alphabet: the letters we are shifting in the cipher
offset: the number of letters we are shifting
message: the message we are trying to decode/encode
command: whether we are going to encode or decode
Outputs:
We want to output a new string.
Constraints: N/A
Edge cases: N/A

To start let's make a container to hold our new string. Because I prefer to use array methods to string methods I am going to use an empty results array. You could also use a string and concat the new letters into the string. 

Next, we are going to do a little cheat. We are going to add the alphabet string parameter to itself so that if the letter we are shifting is towards the end of the alphabet, it can still be shifted. 

I call this cheating because this will only work if the number we are shifting by is less than the length of the alphabet. If someone wants to shift by a number larger than that, they are trying too hard anyway. 

Since we know we are intending to return a string we can return result joined into a string. 

The basic setup without logic is below. 
 ``` 
const caesarCipher = (options) => {
  let { alphabet, offset, message, command } = options;
  let result = [];
   alphabet += alphabet;
      return result.join('');
};
```
We are out of excuses, now for logic. 
Since our message input is a string and we are stubborn and prefer working with arrays we will first split the message into an array. Then we will loop over the array, and declare the variable index which will be the result of the indexOf the letter in the given alphabet. This indexOf method is great because if the letter is not found in the given alphabet indexOf returns -1. We can use this tool to make sure those characters stay the same. Spaces will now be accounted for. 

Now that we have handled the letters we don't need to change we can change the letters we do need to change. If the command is "encode" we will shift the letters forward by the offset number.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/14bomi4i08rnmuzwb01s.png)

Else if the command is "decode" we will shift the letters backward by the offset number.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/4qebp99thnzn31io8gdf.png)

Let's take a look at the final code for our Ceaser cipher. 
```
const ceasarCipher = (options) => {
  let { alphabet, offset, message, command } = options;
  let result = [];
   alphabet += alphabet;
  message.split('').forEach(letter => {
    let index = alphabet.indexOf(letter);
        if(index === -1){
        result.push(letter);
        } else if(command === 'encode'){
           result.push(alphabet[index + offset]);
        } else {
          result.push(alphabet[index - offset]);
        }
  });
      return result.join('');
};
```