Wednesday, 4 August 2021

Web Tutorial: The Encryptor/Decryptor

Sometimes code projects can be whimsical. Years ago, I was watching this Gerard Butler movie, Geostorm. It was utterly forgettable overall, but one part inspired me to go home and begin coding.

Butler's character was exchanging secret messages with his onscreen brother. There would be a block of text, and a cipher key consisting of a series of numbers. Using the key, words were extracted from the block of text to form the secret message. A simple idea, and one which I was itching to try out in code.

And today, we are going to do just that. This will be in PHP, with a HTML interface.

How it works

For example, take this wall of text.
Worshippers beware. In the book of Revelations, praise the Lord. Each day is a new opportunity. Day or night, we must be on guard and watch our every move.


And this key.
243645

 
The first number is 2, so take the 2nd word from the wall of text.
Worshippers beware. In the book of Revelations, praise the Lord. Each day is a new opportunity. Day or night, we must be on guard and watch our every move.


beware.


The next number is 4, so take the 4th word from the wall of text, counting from the last word picked.
Worshippers beware. In the book of Revelations, praise the Lord. Each day is a new opportunity. Day or night, we must be on guard and watch our every move.


beware. of


And so on, and so for. The entire message says "beware. of the new night, guard". Basically, beware of the new night guard.
Worshippers beware. In the book of Revelations, praise the Lord. Each day is a new opportunity. Day or night, we must be on guard and watch our every move.


So now you know how it works. Let's get to coding!

Here's some HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>The Encryptor/Decryptor</title>
        <script>

        </script>
    </head>

    <body>

    </body>
</html>


Create the JavaScript function, decrypt(). Leave it alone for now.
<script>
    function decrypt()
    {

    }
</script>


In the HTML body, we need a placeholder div to display decrypted text. The id will be txtMessageDecrypt. We'll also need a form. The form won't be used right away, but its contents will be.
<body>
    <div id="txtMessageDecrypt">

    </div>

    <form method="POST" action="index.php">

    </form>

</body>


Within the form, we need some more elements. First, a textarea tag to type the message in. Then a text input to enter in the key. And finally, a button to decrypt. It will call the decrypt() function.
<form method="POST" action="index.php">
    <textarea id="txtMessageEncrypt" name="txtMessageEncrypt" rows="15" cols="100"></textarea>

    <br /><br />

    Key:
    <input id="txtKey" name="txtKey" value="">

    <br /><br />

    <input type="button" onclick="decrypt();" value="Decrypt">

</form>


And here's the result.


Now we will focus on the decrypt() function. We first declare variables txtEnc, txtDec and txtKey, assigning to them the elements referenced by txtMessageEncrypt, txtMessageDecrypt and txtKey.
<script>
    function decrypt()
    {
        var txtEnc = document.getElementById("txtMessageEncrypt");
        var txtDec = document.getElementById("txtMessageDecrypt");
        var txtKey = document.getElementById("txtKey");

    }
</script>


We now derive words from txtEnc. It will be an array of all the words in txtEnc's text content.
function decrypt()
{
    var txtEnc = document.getElementById("txtMessageEncrypt");
    var txtDec = document.getElementById("txtMessageDecrypt");
    var txtKey = document.getElementById("txtKey");

    var words = txtEnc.value.split(" ");
}


We derive decryptor the same way, from txtKey. This will be an array of all the characters in txtKey's text value.
function decrypt()
{
    var txtEnc = document.getElementById("txtMessageEncrypt");
    var txtDec = document.getElementById("txtMessageDecrypt");
    var txtKey = document.getElementById("txtKey");

    var words = txtEnc.value.split(" ");
    var decryptor = txtKey.value.split("");
}


And then we define a variable, encrytable, and set it to true by default. This will determine if the values of words and decryptor are suitable for decryption.
function decrypt()
{
    var txtEnc = document.getElementById("txtMessageEncrypt");
    var txtDec = document.getElementById("txtMessageDecrypt");
    var txtKey = document.getElementById("txtKey");

    var words = txtEnc.value.split(" ");
    var decryptor = txtKey.value.split("");
    var encryptable = true;
}


Now if either words or decryptor are empty, encryptable is false. Because we can't encrypt an empty string or use an empty key to encrypt.
var words = txtEnc.value.split(" ");
var decryptor = txtKey.value.split("");
var encryptable = true;

if (words.length == 0 || decryptor.length == 0)
{
    encryptable = false;
}



Then we check for lengths. If decryptor has more characters than words has words, then encryption is impossible as well.
if (words.length == 0 || decryptor.length == 0)
{
    encryptable = false;
}
else
{
    if (decryptor.length > words.length) encryptable = false;
}


Finally, we run through each of decryptor's characters. If any of the characters are 0 or not a number, encryptable is false. This means that decryptor must be made of numbers greater than 0.
if (words.length == 0 || decryptor.length == 0)
{
    encryptable = false;
}
else
{
    if (decryptor.length > words.length) encryptable = false;

    for (var i = 0; i < decryptor.length; i++)
    {
        if (decryptor[i] == "0" || isNaN(decryptor[i])) encryptable = false;
    }

}


Now, declare a variable, decrypted.
if (words.length == 0 || decryptor.length == 0)
{
    encryptable = false;
}
else
{
    if (decryptor.length > words.length) encryptable = false;

    for (var i = 0; i < decryptor.length; i++)
    {
        if (decryptor[i] == "0" || isNaN(decryptor[i])) encryptable = false;
    }
}

var decrypted = "";


The next step will be performed only if encryptable is true.
var decrypted = "";

if (encryptable)
{

}


Inside this If block, we declare ptr and set it to -1. Now we iterate through each element in decryptor.
var decrypted = "";

if (encryptable)
{
    var ptr = -1;

    for (var i = 0; i < decryptor.length; i++)
    {

    }

}


In the For loop, increment ptr by the value of the current element. And then grab the word by using ptr to reference the array words, and add the word to the string decrypted, along with a space.
var decrypted = "";

if (encryptable)
{
    var ptr = -1;

    for (var i = 0; i < decryptor.length; i++)
    {
        ptr += parseInt(decryptor[i]);
        decrypted += words[ptr] + " ";

    }
}


And finally, place the entire string decrypted inside txtDec.
var decrypted = "";

if (encryptable)
{
    var ptr = -1;

    for (var i = 0; i < decryptor.length; i++)
    {
        ptr += parseInt(decryptor[i]);
        decrypted += words[ptr] + " ";
    }

    txtDec.innerHTML = decrypted;
}


Let's try the example I gave earlier.


Now use this key.


Click Decrypt, and this happens!


More functionality

To add more value to this little application, let's go ahead and add en email feature. We already have a form tag, so let us add an email field and button.
<form method="POST" action="index.php">
    <textarea id="txtMessageEncrypt" name="txtMessageEncrypt" rows="15" cols="100"><?php echo $message;?></textarea>

    <br /><br />

    Key:
    <input id="txtKey" name="txtKey" value="">

    <br /><br />

    <input type="button" onclick="decrypt();" value="Decrypt">

    <br /><br />

    <input id="txtEmail" name="txtEmail" value="">
    <input type="submit" value="Send Message">

</form>


Here's how it should look. It's not pretty, but it's functional.


What we now need is PHP to handle the data. We first check if txtEmail has been sent by POST.
<body>
    <?php
        if (isset($_POST["txtEmail"]))
        {

        }
    ?>

    <div id="txtMessageDecrypt">

    </div>


If so, we create a message incorporating the encrypted message in a link.
<body>
    <?php
        if (isset($_POST["txtEmail"]))
        {
            $html = "You have received a message.\n";
            $html .= "Visit the link http://localhost/encryptor/index.php?message=". urlencode($_POST["txtMessageEncrypt"]) ." to decrypt it ";
            $html .= "using your decryptor key.\n";

        }
    ?>
    <div id="txtMessageDecrypt">

    </div>


Here, we create a subject and send the email.
<body>
    <?php
        if (isset($_POST["txtEmail"]))
        {
            $html = "You have received a message.\n";
            $html .= "Visit the link http://www.teochewthunder.com/demo/encryptor/index.php?message=". urlencode($_POST["txtMessageEncrypt"]) ." to decrypt it ";
            $html .= "using your decryptor key.\n";

            $subject = "This is a Decryptor test";

            if (mail ($_POST["txtEmail"], $subject , $html))
            {
                echo "Mail sent";
            }

        }
    ?>
    <div id="txtMessageDecrypt">

    </div>






Depending on your local server email settings, you should receive an email. There's a link in that email that incorporates the encrypted message.


Let's add a bit of code at the start of the PHP block to handle this. Declare the variable, message. Then set message to get the value from the URL if it exists.
<?php
    $message = "";

    if (isset($_GET["message"]))
    {
        $message = $_GET["message"];
    }


    if (isset($_POST["txtEmail"]))
    {


Then insert this into the textbox.
<textarea id="txtMessageEncrypt" name="txtMessageEncrypt" rows="15" cols="100"><?php echo $message;?></textarea>


Now when you click that link, the message is displayed! And you can then proceed to decrypt it using your key.


Final words

This isn't the best way to implement it, of course. In some areas, it's actually rather clumsy. But you can definitely see the idea behind it, and sometimes that's what happens. Feel free to implement your own encryption!

Cryptically yours,
T___T

No comments:

Post a Comment