Lab 3: Encrypt-It!

Overview

In this lab, you will be practicing using forms and JavaScript code to perform some operations on user input. We have provided encrypt-it.html as a starting HTML for you to use and build upon. You don't need to write any CSS in this lab, although you're free to add styling on your own!

Refer to the past few lecture slides for any needed JavaScript review!

Part I: Create the UI Elements

The first task is to extend encrypt-it.html by adding UI controls. Add HTML code for the following:

  • A field for users to enter large (multi-line) amounts of text. It should be 10 rows by 60 columns in side and wrapped in a bordered field set box with the label "Text to Encrypt".
  • Add a second bordered field set box labeled "Encrypt Options" that contains:
    • A button labeled: "Encrypt-It!"
    • A dropdown menu with the options, "Shift Cipher" and "Randomized", preceded by the boldly-emphasized label: "Cipher Type:"
  • Note: Controls are sometimes used in forms, but you must not use the form tag on your page.
  • Expected output is provided on the slide below.

Part I: Expected Output

Encrypt-It Part I

Part II: Write the start of encrypt-it.js

Now you'll write a bit of JavaScript testing code that pops up an alert box. This is just a test to make sure that your browser is running your JavaScript file, before we move on to the main execises.

  • Create a new file and save it as encrypt-it.js
  • Put the following line of code into the file: alert("Hello world!");
  • Link your HTML page to your JavaScript file using a script tag
  • Refresh your page in the browser. Do you see the alert message? If so, move on. Otherwise, double-check your script tag syntax or ask a TA for help

Part III: Hello World Button

Now let's set up a very basic JS event handler. Modify your JS code and HTML so that the "Hello, world!" alert message won't pop up until the user clicks the "Encrypt-It!" button.

  • Modify your JS file to wrap the alert into a fuction
  • Write a window.onload function to set up an onclick event handler for the "Encrypt-It!" button. This handler should call your new function
  • Refresh your page in the browser. Click the button. Do you see the alert? If so, move on. Otherwise, double-check your onclick and window.onload syntax and function, or ask a TA for help

Part IV: Implement a Basic Shift-Cipher

Modify your JS code so that when the user clicks "Encrypt-It!", the text in the input text area will be encrypted using a basic shift-cipher, and output into the page's div with the ID output.

  • Make sure that your text area has an ID attribute so your JS code can talk to it
  • Modify your JS function so that it now takes the text area's text and generates a shift cipher (algorithm discussed on the slide below)

Part IV: The Shift-Cipher Algorithm

The rules of a shift cipher are fairly straightforward. Let the English alphabet we all know and love(?) be called A. Let the shift-encrypted alphabet be called C. For simplicity, we will shift letters in our encryption function by 1 letter. Then C is defined as mapping each letters in A to the letter alphabetically next. For example, 'a' is mapped to 'b', 'b' is mapped to 'c', ... and 'z' is mapped to 'a' (creating a cycle of 26 letters). In this exercise, we will consider uppercase letters and lowercase letters equivalent to one another (ie, 'a' is considered equal to 'A').

Your task in this part is to convert the text in the input text area from alphabet A to alphabet C. This is all you need to know to implement the cipher in this lab, but if you would like additional hints, there are some provided in the slide below.

You may find charCodeAt(index) and fromCharCode(asciiNum) helpful for this problem.

Part IV: Hints

Note that the value you get from the text area is just a long string. So your goal is to build up a new string that is the result of applying the cipher to each letter in the input text, in order, and adding it to your result string.

Visually, the cipher can be represented as the following:


input letter     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
                 | | | | | | | | | | | | | | | | | | | | | | | | | |
                 v v v v v v v v v v v v v v v v v v v v v v v v v v
output letter    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
            

There are a few ways to go about this, but note that one of the most intuitive approaches would be to use a for loop through the input string and add 1 to each letter (letters are actually represented by numerical values, so this is a natural operation). To handle the z -> a shift, you can add a special case for each letter, or use mod arithmetic to avoid this extra case.

If you get stuck on this function, you may refer to a sample solution on the slide below. But it's strongly recommended you implement it on your own.

Part IV: Algorithm Solution

If you're having trouble with the algorithm, one function solution is given below (you can also solve this with arrays):

              
              /**
               * Returns an encrypted version of the given text, where
               * each letter is shifted alphabetically ahead by 1 letter,
               * and 'z' is shifted to 'a' (creating an alphabetical cycle).
               */
              function shiftCipher(text) {
                text = text.toLowerCase();
                let result = "";
                for (let i = 0; i < text.length; i++) {
                  if (text[i] < 'a' || text[i] > 'z') {
                    result += text[i];
                  } else if (text[i] == 'z') {
                    result += 'a';
                  } else { // letter is between 'a' and 'y'
                    let letter = text.charCodeAt(i); 
                    let resultLetter = String.fromCharCode(letter + 1);
                    result += resultLetter;
                  }
                }
                return result;
              }
              
            

Part V: Implement UI Functionality

Now that you have a cool encryption feature implemented, let's add some features for the user to decorate their encrypted message.

First, we want to restrict the shift cipher functionality to only work when "Shift Cipher" is selected in the drop down menu. Only when this is the currently-selected option and then the "Encrypt-It" button is clicked should the input text be encrypted.

Add a "Reset" button to your HTML with an id of reset. When the button is clicked, the text area and the output div should both be cleared.

Add a checkbox element following the boldy-emphasized label "All Caps:" that when checked, makes all of the text in the output div appear only in uppercase (recall the text-transform CSS style). If not checked, it should use whatever casing used in the original input text.

Add a radio button element to the fieldset with two font size options: 12pt and 24pt. The text in the output div should have the fontsize of whatever is currently selected in the radio button group. The radio buttons should follow a boldly-emphasized label, "Font Size:"

Expected output after all of the UI elements are added is provided on the slide below.

Part V: Expected Output

Part V UI

Part VI: Implementing the Randomized Cipher

In this part, you will implement the "Randomized" cipher option. This is similar to the Shift Cipher, only "result alphabet" C is randomly-generated. In otherwords, each letter in the English alphabet is mapped to one of the 25 other letters, but no two letters may have the same mapping (e.g., "a" and "c" can not both map to "d").

First, you should modify your button event handler to determine whether the "Shift Cipher" or "Randomized Cipher" option is selected in the dropdown menu. If the "Randomized Cipher" option is selected, it should call a new function which outputs a randomized encrypted version of the input text area to the output div.

If you would like some hints for writing this algorithm, there are some in the slides below.

Part VI: Hints

Because we aren't simply adding 1 to each letter (or mapping 'a' to 'z'), you might find an array helpful when creating a random cipher alphabet. One way to randomly-generate the cipher is to keep track of unchosen letters in the English alphabet using a string or array. Then, randomly choose one of the unchosen letters (you may find Math.floor() and Math.random() useful here).

Next, push this randomly-chosen letter to the end of the cipher array. Continue this process until you have removed all letters from your English alphabet and have 26 letters in your cipher array (where the first index is the letter randomly-chosen first, and the last index is the letter that was chosen last).

If you get stuck on this function, you may refer to a sample solution on the slide below. But it's strongly recommended you implement it on your own.

Part VI: Algorithm Solution

One possible solution is given below:


function generateCipher(text) {
  let alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
  let cipher = [];
  // it's poor style to hardcode a magic number like 26
  let alphabetLength = alphabet.length;
  for (let i = 0; i < alphabetLength; i++) {
    let randomIndex = Math.floor(Math.random() * alphabet.length);
    cipher.push(alphabet.splice(
      [Math.floor(Math.random() * alphabet.length)], 1));
  }
  $("output").innerText = cipher;
  let result = "";
  for (let i = 0; i < outputText.length; i++) {
    if (text[i] >= 'a' && text[i] <= 'z') {
      let letterCode = text.charCodeAt(i) - 'a'.charCodeAt(0);
      result += cipher[letterCode];
    } else {
      result += text[i];
    }
  }
  $("output").innerText = result.replace(",", "");
}

              

JS

Challenge Problems

Did you enjoy making your own encrypted messages? Here are a few other ideas to add to your file:

  • Add a dropdown menu to select a value to shift by in the Shift Cipher
  • Adjust your ciphers so that digits 0-9 can be encrypted as well as letters
  • Change your cipher to output something other than letters): For example, you could output using emojis, gifs, colored boxes, etc.
  • Write a "Decryption" tool! This goes beyond the scope of this lab, but with a .txt file of dictionary words, you can try to write a tool that takes input (probably from a Shift or Randomized cipher) and tries to decode it, matching sequences of characters to words in the dictionary.