Files
LiberPrayground/results/analysis.html
2021-03-01 23:39:18 +01:00

258 lines
13 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0" />
<title>Cipher Analysis</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="analysis.js?2"></script>
</head>
<body>
<nav class="small">
<a href="./index.html" class="home"></a>
<a href="#top">Top</a>
<a href="#count">Count</a>
<a href="#double-letter">Double-Letter</a>
<a href="#ioc">IoC</a>
<a href="#mod-ioc">Mod-IoC</a>
<a href="#pattern-ioc">Pattern-IoC</a>
<a href="#running-ioc">Running-IoC</a>
<a href="#concealment">Concealment</a>
</nav>
<h1 id="top">Cipher Analysis</h1>
<p>
A few things beforehand: The colored cells you see indicate either value importance or simply display the range of the shown numbers.
For example, the color in the <a href="#count">Count</a> and <a href="#double-letter">Double-Letter Occurrence</a> sections are white for the lowest value, and black for the highest value.
</p>
<p>
For all Index of Occurrence (IoC) sections the color of the cell indicates how good the prediction is.
Higher IoC values are usually associated with more “normal” english text (see section <a href="#ioc">IoC</a> for a quick recap).
Values below 1.25 are white; values above 1.65 are dark.
</p>
<p>
A different color coding scheme is used for the letter per keylen value. This color range depends on the alphabet length.
Since IoC calculations are not reliable at very low input texts, we mark these cells as well.
We require the input to be at least 0.9x as long as the alphabet.
Of course this is still too little text for IoC, but most frequent letters will appear anyway (and probably multiple times).
Texts that are 3x as long as the alphabet are considered good length.
</p>
<dl>
<dt><label for="abc">Alphabet:</label></dt>
<dd>
<input id="abc" style="width: 250px" type="text" value="ᚠᚢᚦᚩᚱᚳᚷᚹᚻᚾᛁᛄᛇᛈᛉᛋᛏᛒᛖᛗᛚᛝᛟᛞᚪᚫᚣᛡᛠ">
<span class="small">⤳ everything else is treated as whitespace</span>
</dd>
<dt><label for="abc_123">Translate to:</label></dt>
<dd>
<input id="abc_123" style="width: 400px" type="text" value="F U TH O R C G W H N I J EO P X S T B E M L NG OE D A AE Y IA EA">
<span class="small">⤳ separated by space, currently only used in concealment analysis</span>
</dd>
<dt><label for="input">Input:</label></dt>
<dd><textarea id="input" cols="60" rows="10">
ᛋᚻᛖᚩᚷᛗᛡᚠ•ᛋᚣᛖᛝᚳ⁜ᚦᛄᚷᚫ•ᚠᛄᛟ•
ᚩᚾᚦ•ᚾᛖᚹᛒᚪᛋᛟᛇᛁᛝᚢ•ᚾᚫᚷᛁᚦ•ᚻᛒᚾᛡ•
ᛈᛒᚾ•ᛇᛄᚦ•ᚪᛝᚣᛉ•ᛒᛞᛈ•ᛖᛡᚠᛉᚷᚠ•
ᛋᛈᛏᚠᛈᚢᛝᚣᛝᛉᛡ•ᚣᚻ•ᛒᚢ•ᚷᚩᛈ•ᛝᚫᚦ•ᛁ
ᚫᚻᛉᚦᛈᚷ•ᚣᚠᛝᚳᛄ•ᚦᚪᛗᛁᛝᛁᛡᚣ•ᚻᛇ•ᛏᚻᚫ
ᛡ•ᛉᚣ•ᛖᚢᛝ•ᚳᚠᚾ•ᛇᚦᛄᛁᚦ•ᚦᛈ•ᚣᛝᛠ•ᚣᚾ
ᛖᚣ•ᛞᛉᛝᚹ•ᛒᚳᛉᛞᛒᚠ•ᛗᛏᚾᛖ•ᛠᛄᚾᛚᚷ
ᛒ•ᛉᚷᚦ⁘ᚣᛁᛞᚪ•ᛝᚷᛗᛄᚱᚩᛚᛇ•ᚣᛏᛈᛁᚦᛞᛄ•
ᛟᚻᛚ•ᛠ•ᚠᛉᚫᛈᚷᛉ•ᚠᛚᚹᛇᛏᚫ•ᚠᚷᚾ•ᛗᛇᛚᚾ•
ᛝᛗᚠᚱᛡ•ᚪᛋ•ᛠᛗᛝᛉᛉᛇᛞᛒ•ᛟᛞᛗᚩ•ᛠ
ᛇᚻ•ᛞᛝᚷ•ᛟᛝᛚᚢᚱᚾᛏ•ᚫᛋᚣᚢᚻᚱᛏ•ᚻᚳ•ᛋᛟ
ᛏᛟᛝᚢᚱ•ᛋ•ᚠᚩᛖᚹᛠᛟᛚᚠᚫ•ᛗᚱᛝ•ᛞᚪᛗᚱ•ᚹ
ᚪᛁᛗᛋᚾ•ᛋᛟᚱᚢᚹᛋᛚᛡ⁘ᛟᚪᚫᛝᛋᛞᛈᛏ•ᚳᚱᚦ
ᛡ•ᚱᛒᚩᛞᚦᚠ•ᚣᛉᛁᛏ⁘ᛟᛁ•ᚠᛚᚩ•ᚠᛠ•ᚱᚩᛟᛗᚻ
ᛗᚷᛈᚻ•ᚫᚻᚾᚩᚻᚣ•ᛟᛋᛚ•ᚾᚷ•ᚫᚣ•ᛟᚳᛒᛚᛄ•ᛝ
ᛚᛟ•ᚫᛄᛠᚹ•ᛠᚦᚩ•ᛒᛟᚣ•ᚳᚠᚳᛄ•ᛚᚫ⁘ᚾ•ᚦᛈ•
ᚢᛉ•ᛟᛉᚷ•ᛈᚠᛋᛇᚫᛟ•ᛝᛈᛇᚩᛖᚪ•ᚷᚫᛡᛝᚦᚩ
•ᛈᚪᛟᚦᚱᛝᚫ•ᚳᛋᛒᛇᚣᚻ•ᛏᛉᛖᛚᚱ⁘ᚷᚹᚣ•ᛄᚠ
ᛁᚾᛡᚳᚣᛠᛁᛡ•ᚩᚦ•ᛖᚳᚫᚳᛉᛡᛠ•ᚩᛚᚳ•ᚠᚱ
ᛞᛝᛖᚢ•ᛞᚳᛚᛠᛋᛉᚳᚷᛡ⁘ᚹᛋᚦ•ᚠᛞᛝ•ᛁᛡ
ᛗᚪᚫᚷ•ᚹᛋ•ᚾᛞ•ᚳᛈᚦᛉᛈᛠᛠ•ᚹᚢ•ᛠᚹ•ᚠᚹ
ᛄᚣ•ᛉᛞᚹᚳᚷᚳᛟ•ᛞᛉᛟ•ᚱᛡᚷ•ᚾᛈᚪᚣᛈ•ᚳ
ᚣᚻ•ᚠᛖᛄᛠᚾ•ᛟᚫ•ᚢᚪ•ᚻᚱ•ᛖᛠᚦᚠᛄᚪ•ᛚᛉ
ᛋᛏ•ᛗᚠᛚᚠᛏ•ᚷᛁᚦ•ᚢᛚᚷ•ᛉᛠᛏᛋᛚᛄᛈ•ᛚᛉᛁ
ᛟᛗ•ᚢ⁘ᚻᛏ•ᛒᛇᛚᛞᚻᛒᛗ•ᛠᚱᛒ•ᚾᚻᛒᛖᚷᛇ•
ᛞᛚᚹᛇᛡᛈᚩ•ᚻᛖᛠ•ᚹᛁᚱᛁᚻ•ᚢᚦᚻᚣ•ᚾᛉᛒᚷᛄ
ᛈᚢ•ᛝᛠᚠᚾᛁᛖᛞᛡᛝᚱ•ᛞᛒᛄᛡᛟᛗᛁ•ᚠᛏ•ᛄ
ᛞᛁᚦᚱᛚᛋ•ᛖᛇᚩᚷᛒᛏᛞ•ᚦᚪᚾᚳᚣ•ᛡᛋᚦᛞ•ᛝᚠᛚ
ᛖᚷᚻᚳ•ᛖᚩᛁᛏᚾᛉ•ᛈᛏᚠᚻᚱᛞᛖᚠᛏ•ᚫᚹᚻ•ᛒ
ᚳ•ᚠ•ᛈᚪᛚᚢᛠᚾᛚᛄ•ᛄᚳᛚᚹᛠᛞᚢᛞᛇ•ᛠᛉ
ᛞᚹᚻᛠ•ᚦᛡᚫᚳᛚᛏᚹᛖᛁᚳ•ᛈᛟᛞᚳ•ᚾᚻᚪ•ᚱᛁᚷ
ᚦᛠᛖᛏᚷ•ᚦᚻᚩᛡᚹᚫᛄᛖ•ᛝᛠᛞ•ᚩᚫ•ᚪᛚ•ᛒᛄ
ᚳᚢᛉᛏᚪᛒᛄᛈ•ᚠᛠ•ᚻᛞᚾᛡᚢᛈᛋᚢᚹ⁜
</textarea><br><br>
<label for="fileload">Load from file:</label>
<select id="fileload">
<option value="p0-2">Chapter: p02</option>
<option value="p3-7">Chapter: p37</option>
<option value="p8-14">Chapter: p814</option>
<option value="p15-22">Chapter: p1522</option>
<option value="p23-26">Chapter: p2326</option>
<option value="p27-32">Chapter: p2732</option>
<option value="p33-39">Chapter: p3339</option>
<option value="p40-53">Chapter: p4053</option>
<option value="p54-55">Chapter: p5455</option>
<option value="0_koan_1">Solved: Koan 1 (cipher)</option>
<option value="solved_0_koan_1">Solved: Koan 1 (plain)</option>
<option value="0_loss_of_divinity">Solved: Loss of Divinity (cipher)</option>
<option value="solved_0_loss_of_divinity">Solved: Loss of Divinity (plain)</option>
<option value="0_warning">Solved: Warning (cipher)</option>
<option value="solved_0_warning">Solved: Warning (plain)</option>
<option value="0_welcome">Solved: Welcome (cipher)</option>
<option value="solved_0_welcome">Solved: Welcome (plain)</option>
<option value="0_wisdom">Solved: Wisdom (cipher)</option>
<option value="solved_0_wisdom">Solved: Wisdom (plain)</option>
<option value="jpg107-167">Solved: jpg107-167 (cipher)</option>
<option value="solved_jpg107-167">Solved: jpg107-167 (plain)</option>
<option value="jpg229">Solved: jpg229 (cipher)</option>
<option value="solved_jpg229">Solved: jpg229 (plain)</option>
<option value="p56_an_end">Solved: p56 An End (cipher)</option>
<option value="solved_p56_an_end">Solved: p56 An End (plain)</option>
<option value="p57_parable">Solved: p57 Parable (cipher)</option>
<option value="solved_p57_parable">Solved: p57 Parable (plain)</option>
</select>
<button onclick="load_from_file()">load</button>
</dd>
<dt>IoC color range:</dt>
<dd>
<label for="ioc_min">white:</label>
<input id="ioc_min" type="number" value="1.25" step="0.05" placeholder="1.25">
<label for="ioc_max">dark:</label>
<input id="ioc_max" type="number" value="1.65" step="0.05" placeholder="1.65">
(rune-english: 1.77)
</dd>
<dt><label for="btn_analyze">Analyze:</label></dt>
<dd>
<button id="btn_analyze" onclick="start_analyze()">Analyze</button>
<input id="chk_nonl" type="checkbox" checked>
<label for="chk_nonl">Ignore newline</label>
</dd>
</dl>
<h2 id="count">Count</h2>
<p>
2-grams, 3-grams, and 4-grams are selected with a moving window.
So, ABCD will have the 2-grams AB, BC, and CD.
For bi-grams, the first letter is row, the second its column.
Hover on a cell to see the actual n-gram.
</p>
<div id="sec_counts">[…]</div>
<h2 id="double-letter">Double-Letter Occurrence</h2>
<p>
The following analysis looks at two neighboring letters.
Whenever two identical letters appear one after another, the number sequence will print a “1” on dark background.
</p>
<p>
Letter difference looks at the shortest distance between two neighbors.
Maximum value is alphabet length / 2, if they are farthest apart.
The value is zero if they are identical.
</p>
<p>
<b>Note:</b> Hover on a cell to see the offset (count using non-whitespace only).
</p>
<div id="sec_double">[…]</div>
<h2 id="ioc">Index of Coincidence (IoC)</h2>
<p>
Quick IoC recap: Normal rune-english IoC is about 1.77.
Values below 1.4 are highly unlikely to be anywhat meaningful.
Predicting english text with IoC gets worse if the text is very short.
</p>
<p>
Here, we look at periodic ciphers (e.g., Vigenere) and split the input text into different key lengths (132).
With a key length of 5, every fifth letter will be decrypted with the same alphabet.
This does not take into account possible interrupts (commonly used in the Liber Primus); if you are interested, there are a few <a href="./index.html#analysis-w-interrupt">analyses</a> on these.
</p>
<p>
<b>Note:</b> Look at the letter per key length value first, if the cell is white, the IoC calculation is not reliable!
</p>
<div id="sec_ioc">[…]</div>
<h2 id="mod-ioc">Modulo IoC</h2>
<p>
This section explores the idea of multiple alphabet-sets alternating.
For example, have two or three Vigenere ciphers that switch after each letter.
A Vigenere with key length 3 (ABC) plus another Vigenere with key length 4 (DEFG) will generate a pattern that only repeats after 24 letters (ADBECFAGBDCEAFBGCDAEBFCG).
So, the first group will represent every 2nd letter (starting with the first), and the second group will also contain every 2nd letter but starting with the second.
Again, this does not take into account interrupts, see <a href="./index.html#analysis-w-interrupt">these</a> results instead.
</p>
<p>
<b>Note:</b> For a key length of 7, indices 0, 14, 28, ... are part of one alphabet, and indices 2, 17, 30, ... are part of another alphabet.
Both are from the same alphabet-set!
</p>
<div id="sec_ioc_mod">[…]</div>
<h2 id="pattern-ioc">Pattern IoC</h2>
<p>
This section looks at different ways to extend a short key into a longer one.
The result of this expansion is still a plain Vigenere-like encryption but the key is so long that we would not be able to find it with IoC analysis.
However, we can use the fact that the same letters appear again and so there are less alphabets than the key length.
</p>
<p>
The two mirror pattern variants simply flip the key in reverse and append it to the original key.
For example, the key ABCD will become ABCDDCBA (Variant A) or ABCDCB (Variant B).
Both keys will repeat after that.
Notice how the first variant produces double letters (DD and AA) and the second does not.
</p>
<p>
The shift pattern simply offsets the key by one and appends this permutation to the key.
For example, ABCD becomes ABCDBCDACDABDABC.
Each key length n (here 4) has n shifts.
A shift of zero is normal Vigenere without permutations.
The example above uses shift = 1; the other two permutations are ABCDCDAB (shift=2) and ABCDDABCCDABBCDA (shift=3).
And again, like with the mirror pattern, we greatly increase the key length without increasing the alphabet count.
</p>
<p>
<b>Note:</b> Shift values greater than its key length, will produce identical patterns; so they are excluded from this table.
Again, this does not take into account interrupts, see <a href="./index.html#analysis-w-interrupt">these</a> results instead.
</p>
<div id="sec_ioc_pattern">[…]</div>
<h2 id="running-ioc">Running IoC</h2>
<p>
This section perfoms a running IoC analysis with a window size on the whole text.
For example, a window size of 50 will calculate the IoC of the first 50 letters.
This will be the first value in the list.
The text is offsetted by one and the next 50 letters are evaluated.
This continues to the last set of 50 letters.
</p>
<p>
Same rules apply as to normal IoC analysis; an IoC on 20 letters is just too small to get a meaningful result.
But it helps to get the bigger picture ;).
</p>
<div id="sec_ioc_flow">[…]</div>
<h2 id="concealment">Concealment Analysis</h2>
<p>
Concealment ciphers hide text in plain sight.
Here, we look at every n-th word, as well as every first and last letter of each word (which is performed on all possible veriations).
</p>
<div id="sec_conceal">[…]</div>
<script type="text/javascript">
const params = new URLSearchParams(window.location.search);
const fname = params.get('file');
if (fname) {
var obj = document.getElementById('fileload');
obj.value = fname;
if (obj.value) {
load_from_file();
} else {
document.getElementById('input').value = 'Error loading file "' + fname + '"';
}
} else {
start_analyze();
}
</script>
</body>
</html>