Skip to content

Instantly share code, notes, and snippets.

@default-work
Last active August 18, 2019 14:34
Show Gist options
  • Save default-work/6d384664bcd0c13a1fc60300920d6fc0 to your computer and use it in GitHub Desktop.
Save default-work/6d384664bcd0c13a1fc60300920d6fc0 to your computer and use it in GitHub Desktop.
Caesar Cipher + 1
<h1>Caesar Cipher +1</h1>
<table>
<tr>
<td style="width:50%;">
<label>Plaintext:</label>
<textarea id='plaintext1'>The atmosphere of Mars is about 100 times thinner than Earth's, and it is 95 percent carbon dioxide. Here's a breakdown of its composition, according to a NASA fact sheet:
Carbon dioxide: 95.32 percent
Nitrogen: 2.7 percent
Argon: 1.6 percent
Oxygen: 0.13 percent
Carbon monoxide: 0.08 percent
Also, minor amounts of: water, nitrogen oxide, neon, hydrogen-deuterium-oxygen, krypton and xenon.</textarea>
<label>Shift:</label>
<input type='number' id='shift1' name='shift' value='88' min='1' max='9999' step='1'>
<input type='button' id='randomize' value='IV'>
<input type='button' id='alphabet_random' value='alphabet'>
<input type='button' id='encrypt' value='encrypt'>
<input type='button' id='apply' value='=>'>
<textarea id='IV1'></textarea>
<textarea id='alphabet1'></textarea>
</td>
<td style="width:50%">
<label>Cipher:</label>
<textarea id='plaintext2'></textarea>
<label>Shift:</label>
<input type='number' id='shift2' name='shift' value='88' min='1' max='9999' step='1'>
<input type='button' id='decrypt' value='decrypt'>
<textarea id='IV2'></textarea>
<textarea id='alphabet2'></textarea>
</td>
</tr>
</table>
<h1>Output:</h1>
<table>
<tr>
<td>
<textarea id='output1'></textarea>
</td>
<td>
<textarea id='output2'></textarea>
</td>
</tr>
</table>
// Artur Mustafin, (c) 2019
// Park & Miller, (c) 1988,1993
const default_alphabet = [
'A','B','C','D','E','F',
'G','H','I','J','K','L',
'M','N','O','P','Q','R',
'S','T','U','V','W','X',
'Y','Z',' ',':',',','*',
'~','!','@','#','%','^',
'-','=','0','1','2','3',
'4','5','6','7','8','9',
'a','b','c','d','e','f',
'g','h','i','j','k','l',
'm','n','o','p','q','r',
's','t','u','v','w','x',
'y','z','"','?','.','_',
'+','(',')','[',']','|',
'{','}','`','\/' //88
];
let alphabet = default_alphabet;
// LCG Park & Miller (c) 1988,1993 (original value proposed was 16807, in 1993 changed to 48271)
// s=>()=>(2**31-1&(s=Math.imul(48271,s)))/2**31
var PRNG = function(seed){
this._seed = seed % 2147483647;
if (this._seed <= 0){ this._seed += 2147483646;}
};
PRNG.prototype.next = function(a,b){
this._seed = this._seed * 48271 % 2147483647; // in response to a criticism by Marsaglia in 1993
if(arguments.length === 0){
return this._seed/2147483647;
}else if(arguments.length === 1){
return (this._seed/2147483647)*a;
}else{
return (this._seed/2147483647)*(b-a)+a;
}
};
var seed = 1238473661;
var rnd = new PRNG(seed);
var random = 0;
var maximus = 2147483647 >> 2;
var enc_offset = 0;
var dec_offset = 0;
Array.prototype.shuffle = function(seed) {
return shuffle(this, seed);
}
Array.prototype.unshuffle = function(seed) {
return unshuffle(this, seed);
}
Array.prototype.offset = function(seed) {
return offset(this, seed);
}
Array.prototype.unoffset = function(seed) {
return unoffset(this, seed);
}
function shuffle(array, seed) {
let rng = new PRNG(seed);
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(rng.next(i));// Math.random() * (i + 1)); // random index from 0 to i
[array[i], array[j]] = [array[j], array[i]]; // swap elements
}
return array;
}
function unshuffle(array, seed) {
let indexes = [];
let rng = new PRNG(seed);
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(rng.next(i));
indexes.push(j);
}
for (let i = 1; i < array.length; i++) {
let j = indexes.pop(); //Math.floor(rng.next(i));// Math.random() * (i + 1)); // random index from 0 to i
[array[i], array[j]] = [array[j], array[i]]; // swap elements
}
return array;
}
function offset(array, offset) {
let length = array.length;
for (let i = length - 1; i > 0; i--) {
let j = (2*maximus + i + offset)%length;
[array[i], array[j]] = [array[j], array[i]]; // swap elements
}
return array;
}
function unoffset(array, offset) {
let length = array.length;
let indexes = [];
for (let i = length - 1; i > 0; i--) {
let j = (2*maximus + i + offset)%length;
indexes.push(j);
}
for (let i = 1; i < length; i++) {
let j = indexes.pop();
[array[i], array[j]] = [array[j], array[i]]; // swap elements
}
return array;
}
function randomInteger(min, max) {
let rand = min + rnd.next() * (max + 1 - min);
return Math.floor(rand);
}
const cipher_size = alphabet.length;
const encrypt = document.getElementById('encrypt');
const decrypt = document.getElementById('decrypt');
const plaintext1 = document.getElementById('plaintext1');
const plaintext2 = document.getElementById('plaintext2');
const output1 = document.getElementById('output1');
const output2 = document.getElementById('output2');
const IV1 = document.getElementById('IV1');
const IV2 = document.getElementById('IV2');
const alpha1 = document.getElementById('alphabet1');
const alpha2 = document.getElementById('alphabet2');
const app = document.getElementById('apply');
const randomize = document.getElementById('randomize');
const alphabet_random = document.getElementById('alphabet_random');
this.random = randomInteger(0,maximus);
IV1.value = this.random;
randomize.addEventListener ('click',event => {
event.preventDefault();
this.random = randomInteger(0,maximus);
this.IV1.value = this.random;
});
alphabet_random.addEventListener ('click',event => {
event.preventDefault();
alphabet = default_alphabet;
alphabet.shuffle(this.random);
alpha1.value = alphabet.join('');
});
encrypt.addEventListener ('click',event => {
event.preventDefault();
this.random = parseInt(this.IV1.value);
alphabet = [... alpha1.value];
this.enc_offset = this.random;
const shift = Number(shift1.value);
let array = [... plaintext1.value ];
for(let i=0; i< shift; i++)
array = array.shuffle(this.random).map(char => shift_encrypt(char, shift));
output1.value = array.offset(this.random).join('');
}
);
app.addEventListener ('click',event => {
event.preventDefault();
this.IV2.value = this.IV1.value;
shift2.value = shift1.value;
alpha2.value = alpha1.value;
plaintext2.value = output1.value;
output2.value = '';
});
decrypt.addEventListener ('click',event => {
event.preventDefault();
this.random = parseInt(this.IV2.value);
alphabet = [... alpha2.value];
this.dec_offset = parseInt(this.IV2.value);
const shift = Number(shift2.value);
let array = [... plaintext2.value ].unoffset(this.random);
for(let i=0; i< shift; i++)
array = array.map(char => shift_decrypt(char, shift)).unshuffle(this.random);
output2.value = array.join('');
}
);
function shift_encrypt(char, shift) {
if (shift%2 == 1) {
char = _encrypt(_encrypt(char,alphabet,shift),alphabet,shift);
} else {
char = _encrypt(_encrypt(char,alphabet.reverse(),0),alphabet.reverse(),0);
}
return char;
}
function shift_decrypt(char, shift) {
if (shift%2 == 1) {
char = _decrypt(_decrypt(char,alphabet,shift),alphabet,shift);
} else {
char = _decrypt(_decrypt(char,alphabet.reverse(),0),alphabet.reverse(),0);
}
return char;
}
function _encrypt(char, alphabet, shift) {
if (alphabet.includes(char))
{
const position = alphabet.indexOf(char);
const newPosition = (2*maximus - position + this.enc_offset - shift)%cipher_size;
this.enc_offset = (++this.enc_offset)%cipher_size;
return alphabet[newPosition]
}
else { return char }
}
function _decrypt(char, alphabet, shift) {
if (alphabet.includes(char))
{
const position = alphabet.indexOf(char);
const newPosition = (2*maximus - position - this.dec_offset - shift)%cipher_size;
this.dec_offset = (++this.dec_offset)%cipher_size;
return alphabet[newPosition]
}
else { return char }
}
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap');
* {
font-family: 'Roboto Mono', sans-serif;
font-size: 10px;
}
body {
font-family: sans-serif;
}
h1,h2 { color: olive;}
label{display:block;}
table {
width: 100%;
}
h1, h2, label, input, textarea {
margin: 5px 5px;
}
textarea {
width: calc(100% - 10px);
height: 120px;
}
#alphabet1, #alphabet2, #IV1, #IV2 {
height: auto;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment