Playfair Cipher Experiments

And now we play....

by Keenan

HTML

<div id="allowedCharacters" class="cipherText"></div>
<p>Input a keyword or keyphrase below. You can use nearly any alpha-numeric characters, including most punctuation. Duplicate characters are ignored when generating the table. The value you input here will determine the overall strength of the cipher. A short or unvaried keyword or phrase will make it easier to crack the code.</p>
<input id="keyword" value="198%H3Ll0-Wor1d!:)" class="cipherText"/>
<br />
<button id="generateKeytable" class="cipherBtn">Generate Key Table</button>
<button id="regenerateKeytable" class="cipherBtn" style="display: none">Regenerate Key Table</button>
<br />
<span id="AfterGen" style="display: none">
    <div id="keyTable" class="cipherKeyTable"></div>
    <p>
        After clicking a button below, the digraph shows what the code does to your message before running it through the cipher. Spaces are converted to underscores and an asterix is used to break up duplicate letter pairs and to fill out uneven pairs. The asterix is trimmed out after deciphering and underscores are returned to spaces.
    </p>
    <pre id="digraph"></pre>
    <textarea id="en" cols="50" rows="5" class="cipherText"></textarea>
    <br/>
    <button id="encipher" class="cipherBtn">Encipher</button><br />
    <br />
    <textarea id="de" cols="50" rows="5" class="cipherText"></textarea>
    <br/>
    <button id="decipher" class="cipherBtn">Decipher</button>
</span>

CSS

body {
    background-color: #F0F0F0;
}
p {
    width: 600px;
    word-wrap: normal;
    margin: 5px;
    padding: 5px;
    border: 1px transparent #000000;
}
.cipherBtn:hover {
    background-color: yellow;
}
.cipherBtn {
    margin:5px;
    padding:5px;
    border:1px solid #000000;
    -moz-border-radius-bottomleft:13px;
    -webkit-border-bottom-left-radius:13px;
    border-bottom-left-radius:13px;
    -moz-border-radius-bottomright:13px;
    -webkit-border-bottom-right-radius:13px;
    border-bottom-right-radius:13px;
    -moz-border-radius-topright:13px;
    -webkit-border-top-right-radius:13px;
    border-top-right-radius:13px;
    -moz-border-radius-topleft:13px;
    -webkit-border-top-left-radius:13px;
    border-top-left-radius:13px;
}
.cipherBtn:focus, .cipherText:focus {
    outline: none !important;
}
.cipherText {
    background-color: #FFFFFF;
    margin:5px;
    padding:5px;
    width:600px;
    border:1px solid #000000;
    font-family: monospace;
    word-wrap: break-word;
    -moz-border-radius-bottomleft:13px;
    -webkit-border-bottom-left-radius:13px;
    border-bottom-left-radius:13px;
    -moz-border-radius-bottomright:13px;
    -webkit-border-bottom-right-radius:13px;
    border-bottom-right-radius:13px;
    -moz-border-radius-topright:13px;
    -webkit-border-top-right-radius:13px;
    border-top-right-radius:13px;
    -moz-border-radius-topleft:13px;
    -webkit-border-top-left-radius:13px;
    border-top-left-radius:13px;
}
.cipherKeyTable {
    margin:25px;
    padding:0px;
    width:300px;
    box-shadow: 10px 10px 5px #888888;
    border:1px solid #000000;
    -moz-border-radius-bottomleft:13px;
    -webkit-border-bottom-left-radius:13px;
    border-bottom-left-radius:13px;
    -moz-border-radius-bottomright:13px;
    -webkit-border-bottom-right-radius:13px;
    border-bottom-right-radius:13px;
    -moz-border-radius-topright:13px;
    -webkit-border-top-right-radius:13px;
    border-top-right-radius:13px;
   ...

JavaScript

//@author Jonathan Walker
//@version 1.1
//@license http://creativecommons.org/licenses/by-sa/4.0/
// Playfair Cipher - Javascript Experimentation
// Enhanced - uses a much larger key table and can retain spaces, case, and punctuation

// Create our cipher object that we will store our data in
jQuery.cipher = {
    key: "", // Initialize a blank key.
    alpha: "", // Stores our alphabet, used for making the key table.
    allowed: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_?1234567890.,!@'%-$()=+<>;:*",
    maxRow: 9, // Rows in the key table.
    maxCol: 9, // Columns in the key table.
    nullCh: '*' // Char used to break up duplicate letters and fill uneven pairs.
};

// HTML Table for our key table.
function printKey() {
    var tableHtml = "<table class=\"keyTable\">";
    for (var i = 0; i < $.cipher.allowed.length; i = i + $.cipher.maxCol) {
        tableHtml += "<tr class=\"keyRow\">";
        var row = $.cipher.key.substring(i, i + $.cipher.maxCol);
        var chars = row.split("");
        for (var x = 0; x < $.cipher.maxCol; x++) {
            tableHtml += "<td class=\"keyValue\">" + chars[x] + "</td>";
        }
        tableHtml += "</tr>";
    }
    tableHtml += "</table>";
    $("#keyTable").html(tableHtml);
}

// Fetches the position of a specific character in the table
function getCharPosition(c) {
    var index = $.cipher.key.indexOf(c);
    var row = Math.floor(index / $.cipher.maxRow);
    var col = index % $.cipher.maxCol;
    return {
        row: row,
        col: col
    };
}

// Fetches a character based on the given position
// Position must be an object with both row and col attributes.
function getCharFromPosition(pos) {
    var index = pos.row * $.cipher.maxRow;
    index = index + pos.col;
    return $.cipher.key.charAt(index);
}

// Applies the Playfair rules to a given set of letters.
function encipherPair(str) {
    if (str.length != 2) return false;
    var pos1 = getCharPosition(str.charAt(0));
    var pos2 =...