This is is a javascript version of the Vigenère Square. It uses the characters that can be found on a US keyboard as it's alphabet. I can't guarentee it to be bug free, but it encrypted and decrypted itself successfully. It keeps case and can handle numbers and special chars. Almost anything you can type with your keyboard. If it can't encode a char it should just pass through without interupting the encrypting of the rest of the message. All tabs (\t and \v) and newlines (\f, \n, and \r) are trimmed out and replaced with a single space. I've tried to make this as usable in the real world as possible.

To see it in action go to http://www.babelfeesh.com/crypto/vigenere.html.

Thank wharfinger for the e2 source code formatter. And for more info see Breaking the Vigenère Square, the Vigenère Square, and One-Time Pad.

Cryptology Meta-Node


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<title>Vigenère Square in Javascript</title>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">

// produce our cipher alphabet for vigenere square
var soup = new Array();
var cnt=0;
soup[cnt++] = " ";
soup[cnt++] = "a";
soup[cnt++] = "b";
soup[cnt++] = "c";
soup[cnt++] = "d";
soup[cnt++] = "e";
soup[cnt++] = "f";
soup[cnt++] = "g";
soup[cnt++] = "h";
soup[cnt++] = "i";
soup[cnt++] = "j";
soup[cnt++] = "k";
soup[cnt++] = "l";
soup[cnt++] = "m";
soup[cnt++] = "n";
soup[cnt++] = "o";
soup[cnt++] = "p";
soup[cnt++] = "q";
soup[cnt++] = "r";
soup[cnt++] = "s";
soup[cnt++] = "t";
soup[cnt++] = "u";
soup[cnt++] = "v";
soup[cnt++] = "w";
soup[cnt++] = "x";
soup[cnt++] = "y";
soup[cnt++] = "z";
soup[cnt++] = "A";
soup[cnt++] = "B";
soup[cnt++] = "C";
soup[cnt++] = "D";
soup[cnt++] = "E";
soup[cnt++] = "F";
soup[cnt++] = "G";
soup[cnt++] = "H";
soup[cnt++] = "I";
soup[cnt++] = "J";
soup[cnt++] = "K";
soup[cnt++] = "L";
soup[cnt++] = "M";
soup[cnt++] = "N";
soup[cnt++] = "O";
soup[cnt++] = "P";
soup[cnt++] = "Q";
soup[cnt++] = "R";
soup[cnt++] = "S";
soup[cnt++] = "T";
soup[cnt++] = "U";
soup[cnt++] = "V";
soup[cnt++] = "W";
soup[cnt++] = "X";
soup[cnt++] = "Y";
soup[cnt++] = "Z";
soup[cnt++] = "`";
soup[cnt++] = "1";
soup[cnt++] = "2";
soup[cnt++] = "3";
soup[cnt++] = "4";
soup[cnt++] = "5";
soup[cnt++] = "6";
soup[cnt++] = "7";
soup[cnt++] = "8";
soup[cnt++] = "9";
soup[cnt++] = "0";
soup[cnt++] = "-";
soup[cnt++] = "=";
soup[cnt++] = "[";
soup[cnt++] = "]";
soup[cnt++] = "\\";
soup[cnt++] = ";";
soup[cnt++] = "'";
soup[cnt++] = ",";
soup[cnt++] = ".";
soup[cnt++] = "/";
soup[cnt++] = "~";
soup[cnt++] = "!";
soup[cnt++] = "@";
soup[cnt++] = "#";
soup[cnt++] = "$";
soup[cnt++] = "%";
soup[cnt++] = "^";
soup[cnt++] = "&";
soup[cnt++] = "*";
soup[cnt++] = "(";
soup[cnt++] = ")";
soup[cnt++] = "_";
soup[cnt++] = "+";
soup[cnt++] = "{";
soup[cnt++] = "}";
soup[cnt++] = "|";
soup[cnt++] = ":";
soup[cnt++] = "\"";
soup[cnt++] = "<";
soup[cnt++] = ">";
soup[cnt++] = "?";

// setup the vigenere square
var encvigsq = new Array();
for (var vi=0; vi < soup.length; vi++) {
    encvigsq[soup[vi]] = new Array();
    for (var vj=0; vj < soup.length; vj++) {
        var letter = vi+vj;
        if (vi+vj > (soup.length - 1)) {
            letter = vi+vj-soup.length;
        }
        encvigsq[soup[vi]][soup[vj]] = soup[letter];
    }
}

// setup an array for decoding the vigenere square
var decvigsq = new Array();
for (var di=0; di < soup.length; di++) {
    decvigsq[soup[di]] = new Array();
    for(var dj=0; dj < soup.length; dj++) {
        decvigsq[soup[di]][encvigsq[soup[di]][soup[dj]]] = soup[dj];
    }
}

/*///////////////////////// encode using the vigenere square ///////////////////*/

function encodevig() {
    // comments 
    var sourceString = document.getElementById("source").value;
    sourceString = sourceString.replace(/[\t\f\n\r\v]+/g, " ");
    var outputString = "";
    var keyString = document.getElementById("vigkey").value;
    keyString = keyString.replace(/[\t\f\n\r\v]+/g, " ");
    var keyidx = 0;
    for (var i = 0; i < sourceString.length; i++) {
        if (encvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)] != null) {
            outputString += encvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)];
            if (keyidx == (keyString.length - 1)) {
                keyidx = 0;
            } else {
                keyidx++;
            }
        } else {
            outputString += sourceString.charAt(i);
        }
    }
    document.getElementById("destination").value = outputString;
}

/*///////////////////////// decode using the vigenere square ///////////////////*/

function decodevig() {
    // comments 
    var sourceString = document.getElementById("source").value;
    sourceString = sourceString.replace(/[\t\f\n\r]+/g, " ");
    var outputString = "";
    var keyString = document.getElementById("vigkey").value;
    keyString = keyString.replace(/[\t\f\n\r\v]+/g, " ");
    var keyidx = 0;
    for (var i = 0; i < sourceString.length; i++){
        if (decvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)]) {
            outputString += decvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)];
            if (keyidx == (keyString.length - 1)) {
                keyidx = 0;
            } else {
                keyidx++;
            }
        } else {
            outputString += sourceString.charAt(i);
        }
    }
    document.getElementById("destination").value = outputString;
}


</script>
</head>

<body>
<h1 align="center">A Vigenère Square in Javascript</h1>
Note: I've used a larger alphabet then most implementations I've found.
It keeps case and can handle numbers and special chars.  Almost anything you
can type with your keyboard.  If it can't encode a char it should just pass
through without interupting the encrypting of the rest of the message. All
tabs (\t and \v) and newlines (\f, \n, and \r) are trimmed out and replaced
with a single space.
<p>
Disclaimer: I don't promise this to be bug free. It is also a well known
algorithm and is not difficult to crack.  Do not use for actual secure
communications.  But if it is bug free it can be used as a One Time Pad which is very secure.
<p>
<textarea id="source" cols=70 rows=10></textarea><br />
<button id="dovig" onclick="encodevig()">Encode (Vigenere Sq)</button>
<button id="undovig" onclick="decodevig()">Decode (Vigenere Sq)</button>
<b>Key:</b> <input id="vigkey" size="20" value="default">
<br />
<textarea id="destination" cols=70 rows=10></textarea>
</body>
</html>
Y'know, if you log in, you can write something here, or contact authors directly on the site. Create a New User if you don't already have an account.