Simple Secret Message App using HTML5, CSS3 and JavaScript.

Maebrie 237
5 min readJun 30, 2023

--

image from img.wonderhowto.com

This article shows a sample of what I made in the second part of my Web development program as a student of rebase academy.
Until today, I have learned HTML5, CSS3 and JavaScript technologies. I will use these languages to build a Secret Message App (SMA), as it was one of the school projects.

I will focus more on JavaScript than the other ones.

  1. An input text field to collect the sentence.
  2. A div to display the first rectangle of normalized text.
  3. A div to show, the encoded message in chunks.
  4. A div to show the second rectangle from the encoded message.
  5. A button to perform the action of encoding.

Note: for this Secret Message App (SMA), the input text should be at least of 2 words, i.e. 4 characters.

So Where to Start ?

I started in my favourite code editor VS Code by creating an index.HTML in the main folder; in a separate empty folder, I added index.js and styles.css in another empty folder. Or You can just go with CodePen and click on the pen to get started. Here, I will dive deeper into JavaScript code.

Setting up HTML and CSS

Since it is a simple project, I introduced everything on one page. On this page, I introduced 5 divs(<div>). Apart from the three mentioned above, I added one to contain the button and the other to contain the input. All of this is in a <main> tag container.

<main class="container">
<div class="div-for-input">
<label for="input-text">Enter the text to encode here.</label>
<input type="text" name="input-text" class="input-text" />
</div>
<div class="first-rectangle">
<span>First rectangle of normalized text : </span>
<div class="rectange"></div>
</div>
<div class="first-chunks">
<span>Encoded message in chunks: </span>
<div class="chunks"></div>
</div>
<div class="second-rectangle">
<span>Second rectangle from the encoded message: </span>
<div class="second"></div>
</div>
<div class="div-btn-action">
<button class="action">Fire Action</button>
</div>
</main>

In the CSS file, I have used linear-gradient() and URL () Methods to change the background of the SMA and to fill the colour as wanted. So, it looks like showing up.

span {
font-style: italic;
font-size: 1rem;
color: blueviolet;
border-radius: 10px;
font-weight: bold;
background-image: linear-gradient(to right, white, #ffff06);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 1.25rem;
}

Making Interactive with JavaScript

I made the App work so that when you enter the text to encode in the input field, and you press or click the button “Fire Action”; the result is displayed.

You’ll see the result only if the entering text length is greater than 4 characters, since the number of rows and columns of the rectangle are computed automatically. I made a function to do just that:

To automatically get the number of rows and columns of the text

Given the fact that the normalized text should be organized into a rectangle, the size of the rectangle (R X C​) can be determined by the length of the message, such that ​C >= R​ and ​c — r >= 1​, where C​ is the number of columns and ​R​ is the number of rows. In the code, I have used “r” and “c” for that. Considering that size = r*c (text length) and c>=r, we can take c = r+k where k is a natural number. We’ll have this equation r²+kr-N=0 solved with N=size, to solve.

For the calculation, we consider the smallest integer after 0, (1); to avoid N=C² and to remain close to N as much as possible ( this make the gap between rows and columns as small as possible). So we consider k = 1: Now we solve the equation r²+r-N=0 and consider only the rounded positive solution between the two solutions. And from that “r”, we can easily get “c” by dividing the smallest multiple of r greater than N by r.

function columsAndRowLength(chaine) {
let N = chaine.length;
let delta = 1 + 4 * N;
//we need just the rounded positive r.
let r = Math.round((-1 + Math.sqrt(delta)) / 2);
// we get smallest multiple of r greater than N.
let nearMultipleOfr = Math.ceil(N / r) * r;
// we get c.
let c = nearMultipleOfr / r;
return [r, c];
}

After getting the number of rows and columns, we can now split the text. To do that, I have written a function:

const splitText = (string, colums) => {
if (string.length > colums) {
let newArray = [],
usedStrings = [];
// to create new array with chunks
for (let i = 0; i < string.length; i += colums) {
newArray.push(string.slice(i, i + colums));
}
// we try to fill the gap of the last substring the array created above in case the rectangle is not perfect
usedStrings = newArray;
let long2 = newArray.length;
// to get the before last element length of newArray
let L2 = usedStrings[long2 - 2].length;
// to get the last element length of newArray
let L1 = usedStrings[long2 - 1].length;
// check if the last substring is shorter than one before.
if (L2 > L1) {
// append '$' character to the last substring
usedStrings[long2 - 1] = usedStrings[long2 - 1].padEnd(L2, "$");
return usedStrings;
}
return newArray;
} else alert("String to short. Need at least 4 characters");
};

In the case where the array created doesn’t have the same substring lengths, we append the ‘$’ character to fill the gap (it can be any other char) to obtain a rectangle. Now, considering this done, we can encode the text by reading the rectangle formed from top to bottom and from left to right and creating a new array of strings. This function do so:

function secretText(newArray) {
let usedArray = [];
let temp = [];
let i = 0,
j = 0;
while (j < newArray[0].length) {
while (i < newArray.length) {
// store every char to temp row after row and from the same column
temp.push(newArray[i][j]);
// next row
i++;
}
// next column
j++;
//come back to line 0
i = 0;
}
return temp.join("");
}

Once we have the normalized, split, get a secret text, we can now display the rectangle text. This function takes care of that :

function rectangle(splitText) {
let newArray = [];
for (let i = 0; i < splitText.length; i++) {
newArray.push(splitText[i] + "<br>");
}
return newArray.join("");
}

Get the complete code here:

https://github.com/frckbrice/secret-message

With the addition of some more basic validations, my SMA is complete !

The deployed version can be meet here: https://frckbrice.github.io/secret-message/

Rebase Academy

--

--