JSFiddle - React, Tailwind, and code Playground
HTML
<h1>(copy for stackoverflow question)</h1>
<label>
Ciphertext:
<br />
<textarea id="ciphertext"></textarea>
</label>
<br />
<button id="decipher">Go</button>
<p>Output:</p>
<pre id="log"></pre>
<p>Plaintext:</p>
<textarea id="plaintext"></textarea>
</body>
</html>
CSS
body {
width: 900px;
margin: 0 auto;
}
pre {
background: #eee;
border: 1px dashed #aaa;
max-height: 150px;
overflow: auto;
word-wrap: break-word;
}
textarea {
width: 100%;
height: 100px;
}
JavaScript
$(document).ready(function(){
$('#decipher').click(Decipher);
});
function Decipher()
{
var $mCipher;
var $mTempCipher;
var $mKeyLength;
var init = function()
{
$('#log').html();
startDeciphering();
}
var startDeciphering = function()
{
log('Starting to decipher');
// normalize the ciphertext to alphanumeric only
$mCipher = normalize( $('#ciphertext').val() );
output($mCipher); // temp
// @todo: try to guess the key length using the Friedman method?
// try to define key length using the Kasiski method
$mKeyLength = defineKeyLength();
// @todo: generic exit function
if(!$mKeyLength) return false;
//
}
var defineKeyLength = function()
{
log('Step 1: Define key length', true);
var $lRecurringStrings = [];
// find recurring strings of decreasing length
for(var $i = 12; $i > 3; $i--) {
console.log("String length:", $i);
$lRecurringStrings = $lRecurringStrings.concat(findRecurringString($i));
}
// show recurring strings or exit
if($lRecurringStrings.length > 0)
log("Recurring strings:" + $lRecurringStrings , true);
else {
log('No recurring strings found :(. Either the key is too long or the ciphertext is too short to break the code.', true);
return false;
}
getDistances();
}
var findRecurringString = function($aLength, $aCallback)
{
log('Finding recurring strings of length ' + $aLength, true)
// use a temp cipher so we can safely replace matched strings without messing up the original
$mTempCipher = $mCipher;
var $lRecurring = [];
// loop through the ciphertext, taking a string of $aLength length and advancing one next letter each step
for(var $i = 0; $i <= $mTempCipher.length - $aLength; $i++) {
log('.');
var $lString = $mTempCipher.substr($i, $aLength);
console.log($i, $mTempCipher.length, $aLength);
listRecurrence({ string: $lString }, function($aData){
// return
$lRecurring.push($aData.string);
});
}
return...