A Pen by Artur Mustafin on CodePen.
Last active
August 17, 2019 19:33
-
-
Save default-work/8e626705ad0bb2864e53e8cad8d88627 to your computer and use it in GitHub Desktop.
Caesar Cipher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Caesar Cipher +1</h1> | |
<table> | |
<tr> | |
<td style="width:50%;"> | |
<form id="enc"> | |
<label>Plaintext:</label> | |
<textarea name='plaintext'>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='32' min='1' max='255'> | |
<input type='button' id='encrypt' value='encrypt'> | |
</form> | |
</td> | |
<td style="width:50%"> | |
<form id="dec"> | |
<label>Cipher:</label> | |
<textarea name='plaintext'></textarea> | |
<label>Shift:</label> | |
<input type='number' id='shift2' name='shift' value='1' min='1' max='255'> | |
<input type='button' id='decrypt' value='decrypt'> | |
</form> | |
</td> | |
</tr> | |
<tr style="height: auto"> | |
<td> | |
<textarea id='IV1' style="height: 100%"></textarea> | |
</td> | |
<td> | |
<textarea id='IV2' style="height: 100%"></textarea> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
</td> | |
</tr> | |
</table> | |
<table style="width:100%"> | |
<tr> | |
<td> | |
<input type='button' id='randomize' value='randomize'> <input type='button' id='apply' value='=>'> | |
</td> | |
</tr> | |
</table> | |
<h1>Output:</h1> | |
<table> | |
<tr> | |
<td> | |
<textarea id='output1'></textarea> | |
</td> | |
<td> | |
<textarea id='output2'></textarea> | |
</td> | |
</tr> | |
</table> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const 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','"','?','.','_', | |
'+','(',')','[',']','|', //84 | |
'{','}','`','\/' //88 | |
]; | |
// 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 >> 1; | |
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.shift = function(seed) { | |
return shift(this, seed); | |
} | |
Array.prototype.unshift = function(seed) { | |
return unshift(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 shift(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 unshift(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 randomInteger(min, max) { | |
let rand = min + rnd.next() * (max + 1 - min); | |
return Math.floor(rand); | |
} | |
const cipher_size = alphabet.length; | |
const enc = document.getElementById('enc'); | |
const dec = document.getElementById('dec'); | |
const output1 = document.getElementById('output1'); | |
const output2 = document.getElementById('output2'); | |
const IV1 = document.getElementById('IV1'); | |
const IV2 = document.getElementById('IV2'); | |
const app = document.getElementById('apply'); | |
this.random = randomInteger(0,maximus); | |
IV1.value = this.random; | |
//IV2.value = this.random; | |
const randomize = document.getElementById('randomize'); | |
randomize.addEventListener ('click',event => { | |
event.preventDefault(); | |
this.random = randomInteger(0,maximus); | |
this.IV1.value = this.random; | |
}); | |
app.addEventListener ('click',event => { | |
event.preventDefault(); | |
this.IV2.value = this.IV1.value; | |
dec.shift.value = enc.shift.value; | |
dec.plaintext.value = output1.innerHTML; | |
}); | |
enc.addEventListener ('click',event => { | |
event.preventDefault(); | |
this.random = parseInt(this.IV1.value); | |
this.enc_offset = this.random; | |
const shift = Number(enc.shift.value); | |
let array = [... enc.plaintext.value ]; | |
for(let i=0; i< shift; i++) | |
array = array.shuffle(this.random).map(char => shift_encrypt(char, shift)); | |
output1.innerHTML = array.join(''); | |
} | |
); | |
dec.addEventListener ('click',event => { | |
event.preventDefault(); | |
this.dec_offset = parseInt(this.IV2.value); | |
const shift = Number(dec.shift.value); | |
let array = [... dec.plaintext.value ]; | |
for(let i=0; i< shift; i++) | |
array = array.map(char => shift_decrypt(char, shift)).unshuffle(this.random); | |
output2.innerHTML = array.join(''); | |
} | |
); | |
function shift_encrypt(char, shift) { | |
for(let i=0; i<shift; i++) | |
{ | |
if (i%2===1) { | |
char = encrypt(char,alphabet); | |
} else { | |
char = encrypt(char,alphabet.reverse()); | |
} | |
} | |
return char; | |
} | |
function shift_decrypt(char, shift) { | |
for(let i=0; i<shift; i++) | |
{ | |
if (i%2===1) { | |
char = decrypt(char,alphabet); | |
} else { | |
char = decrypt(char,alphabet.reverse()); | |
} | |
} | |
return char; | |
} | |
function encrypt(char, alphabet) { | |
if (alphabet.includes(char)) | |
{ | |
const position = alphabet.indexOf(char); | |
const newPosition = (2*maximus + position + this.enc_offset)%cipher_size; | |
this.enc_offset = (++this.enc_offset)%cipher_size; | |
return alphabet[newPosition] | |
} | |
else { return char } | |
} | |
function decrypt(char, alphabet) { | |
if (alphabet.includes(char)) | |
{ | |
const position = alphabet.indexOf(char); | |
const newPosition = (2*maximus + position - this.dec_offset)%cipher_size; | |
this.dec_offset = (++this.dec_offset)%cipher_size; | |
return alphabet[newPosition] | |
} | |
else { return char } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap'); | |
* { | |
font-family: 'Roboto Mono', sans-serif; | |
font-size: 12px; | |
} | |
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: 25px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment