Last active
July 12, 2024 22:26
-
-
Save RepComm/4c12129da0e1dce30be8a4401b50eba6 to your computer and use it in GitHub Desktop.
vigenere cipher experiment html app
This file contains hidden or 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<style> | |
body { | |
margin: 0; | |
height: 100svh; | |
padding: 0; | |
overflow: hidden; | |
font-family: Arial, Helvetica, sans-serif; | |
} | |
.monospace { | |
font-family: 'Courier New', Courier, monospace; | |
} | |
.col { | |
display: flex; | |
flex-direction: column; | |
flex: 1; | |
} | |
textarea { | |
width: 100%; | |
flex: 1; | |
} | |
.row { | |
display: flex; | |
flex: 1; | |
flex-direction: row; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="col"> | |
<div class="col"> | |
<label for="ta_msg">Encrypt</label> | |
<textarea id="ta_msg" class="monospace"></textarea> | |
<label for="ta_dec">Decrypt</label> | |
<textarea id="ta_dec" class="monospace"></textarea> | |
<label for="ta_pwd">Password</label> | |
<textarea id="ta_pwd" class="monospace">password</textarea> | |
</div> | |
<div class="row"> | |
<div class="col"> | |
<label for="ta_tab_key">Vigenere Alphabet Key</label> | |
<textarea id="ta_tab_key" class="monospace">kryptos</textarea> | |
<label for="ta_tab">Cipher Table</label> | |
<textarea id="ta_tab" class="monospace" style="min-height:30em;" readonly></textarea> | |
</div> | |
<div class="col"> | |
<label for="ta_out">Encrypt Output</label> | |
<textarea id="ta_out_enc" class="monospace"></textarea> | |
<label for="ta_out_dec">Decrypt Output</label> | |
<textarea id="ta_out_dec" class="monospace"></textarea> | |
</div> | |
</div> | |
<script> | |
/**@type {HTMLTextAreaElement}*/ | |
const ta_msg = document.getElementById("ta_msg") | |
/**@type {HTMLTextAreaElement}*/ | |
const ta_dec = document.getElementById("ta_dec") | |
/**@type {HTMLTextAreaElement}*/ | |
const ta_pwd = document.getElementById("ta_pwd") | |
/**@type {HTMLTextAreaElement}*/ | |
const ta_out_enc = document.getElementById("ta_out_enc") | |
/**@type {HTMLTextAreaElement}*/ | |
const ta_out_dec = document.getElementById("ta_out_dec") | |
/**@type {HTMLTextAreaElement}*/ | |
const ta_tab = document.getElementById("ta_tab") | |
/**@type {HTMLTextAreaElement}*/ | |
const ta_tab_key = document.getElementById("ta_tab_key") | |
let originalAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
let alphabet = originalAlphabet | |
/**@type {Array<string>}*/ | |
let table = new Array(alphabet.length) | |
function recalc_tab() { | |
alphabet = originalAlphabet | |
let alphabetArr = alphabet.split("") | |
const key = ta_tab_key.value.toUpperCase() | |
if (key !== "") { | |
for (const ch of key) { | |
const idx = alphabetArr.indexOf(ch) | |
if (idx > -1) { | |
alphabetArr.splice(idx, 1) | |
} | |
} | |
const keyArr = key.split("") | |
for (let i = 0; i < keyArr.length; i++) { | |
const ch = keyArr[i] | |
if (keyArr.indexOf(ch, i + 1) > -1) { | |
keyArr.splice(i, 1) | |
} | |
} | |
alphabet = keyArr.join("").concat(alphabetArr.join("")) | |
} | |
// let output = alphabet | |
table[0] = alphabet | |
const row = new Array(alphabet.length) | |
for (let i = 1; i < alphabet.length; i++) { | |
for (let j = 0; j < alphabet.length; j++) { | |
row[j] = alphabet[(j + i) % alphabet.length] | |
} | |
table[i] = row.join("") | |
// output += "\n" + row.join("") | |
} | |
ta_tab.textContent = table.join("\n") | |
} | |
ta_tab_key.onchange = () => { | |
recalc_tab() | |
} | |
recalc_tab() | |
function encrypt_output() { | |
const plain = ta_msg.value.toUpperCase() | |
const password = ta_pwd.value.toUpperCase() | |
let output = "" | |
for (let i = 0; i < plain.length; i++) { | |
const row_ch = plain[i] | |
if (alphabet.indexOf(row_ch) === -1) { | |
output += "?" | |
continue | |
//continue //skip invalid char | |
} | |
const col_ch = password[i % password.length] | |
const row = alphabet.indexOf(row_ch) | |
const col = alphabet.indexOf(col_ch) | |
const sel = table[row][col] | |
// console.log(row_ch, col_ch, sel) | |
output += sel | |
} | |
ta_out_enc.textContent = output | |
} | |
function decrypt_output() { | |
const cipher = ta_dec.value.toUpperCase() | |
const password = ta_pwd.value.toUpperCase() | |
let output = "" | |
for (let i = 0; i < cipher.length; i++) { | |
const row_ch = password[i % password.length] | |
const row = alphabet.indexOf(row_ch) | |
const sel_ch = cipher[i] | |
const row_content = table[row] | |
const col = row_content.indexOf(sel_ch) | |
if (col === -1) { | |
continue //skip invalid char | |
} | |
const original = alphabet[col] | |
// console.log(row_ch, col_ch, sel) | |
output += original | |
} | |
ta_out_dec.textContent = output | |
} | |
ta_msg.onchange = () => { | |
encrypt_output() | |
} | |
ta_pwd.onchange = () => { | |
encrypt_output() | |
decrypt_output() | |
} | |
ta_dec.onchange = ()=>{ | |
decrypt_output() | |
} | |
</script> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment