Skip to content

Instantly share code, notes, and snippets.

@johan-eriksson
Last active May 3, 2018 01:39
Show Gist options
  • Save johan-eriksson/7a1c992320d3ba40cef8ac3eae1ec2a3 to your computer and use it in GitHub Desktop.
Save johan-eriksson/7a1c992320d3ba40cef8ac3eae1ec2a3 to your computer and use it in GitHub Desktop.
Get some visual overview while solving a monoalphabetic substitution cipher
<!DOCTYPE html>
<html>
<head>
<style>*{ font-family: "Monospace", "Courier New"}</style>
<title>Monoalphabetic Substition Helper</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
Ciphertext goes here:<br>
<textarea rows="4" cols="50" id="ciphertext">
</textarea>
<div id="Alphabet">
<table id="alphatable"></table>
</div>
<div id="solvedtext"></div>
<div id="LettersLeft"><table id="letterstable"></table></div>
<script type="text/javascript">
$(document).ready(function()
{
var lettersUsed = [];
var letterstable = document.getElementById("letterstable");
var tmprow = letterstable.insertRow(0);
var lettersrowleft = tmprow.insertCell(0);
var lettersrowright = tmprow.insertCell(1);
var probabilities = { "e":12.702, "t":9.056, "a":8.167, "o":7.507, "i":6.966, "n":6.749,
"s":6.327, "h":6.094, "r":5.987, "d":4.253, "l":4.025, "c":2.782, "u":2.758, "m":2.406,
"w":2.360, "f":2.228, "g":2.015, "y":1.974, "p":1.929, "b":1.492, "v":0.978, "k":0.772,
"j":0.153, "x":0.150, "q":0.095, "z":0.074};
var table = document.getElementById("alphatable");
var row0 = table.insertRow(0);
var row1 = table.insertRow(1);
var alphabet = Object.keys(probabilities).sort().reverse();
for (var c of alphabet) {
var i = 0;
var cell0 = row0.insertCell(i);
var cell1 = row1.insertCell(i);
cell0.innerHTML = c;
cell1.innerHTML = '<input type="text" size=1 id="'+c+'">'
i++;
}
for (var i = Object.keys(probabilities).length - 1; i >= 0; i--) {
var letter = Object.keys(probabilities)[i];
$('#'+letter).on('input', function()
{
var ciphertext = document.getElementById("ciphertext").value.toLowerCase();
lettersUsed = []
var unused = [];
for(var j=0;j<26;j++)
{
var l = Object.keys(probabilities)[j];
var inputletter = document.getElementById(l);
var thehtml = inputletter.value;
if(thehtml==="") unused.push(l);
else lettersUsed.push(thehtml);
}
if(ciphertext.length>0)
{
unusedcipherletterstext = "";
var letterfreqpairs = []
for(var l of unused)
{
var count = (ciphertext.match(new RegExp(l,"g")) || []).length;
letterfreqpairs.push([count/ciphertext.length*100, l])
}
letterfreqpairs.sort(function(a, b)
{
return b[0]-a[0];
});
for(var pair of letterfreqpairs)
{
unusedcipherletterstext = unusedcipherletterstext + pair[1]+" "+pair[0].toFixed(3)+"%<br>";
}
lettersrowright.innerHTML = "Unusued<br> Ciphertext<br> letters<br>"+unusedcipherletterstext;
}
var remains = [];
var remainstext = "Unusued<br> Solutiontext<br> letters<br>"
for(var l of Object.keys(probabilities).filter(c => !lettersUsed.includes(c)))
{
remains.push(l+' '+probabilities[l]+'%<br>');
}
for(var c of remains) remainstext = remainstext + c;
lettersrowleft.innerHTML = remainstext;
var solvedtext = ""
for(var c of ciphertext)
{
var sub = document.getElementById(c.toLowerCase());
if(sub===null) continue;
if(sub.value==="") solvedtext = solvedtext+".";
else solvedtext = solvedtext+sub.value;
}
document.getElementById("solvedtext").innerHTML = solvedtext+"<br>"+ciphertext;
});
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment