Skip to content

Instantly share code, notes, and snippets.

@ElectricCoffee
Last active August 19, 2017 22:44
Show Gist options
  • Save ElectricCoffee/2eb06fcf996ea8fcf6bc19fdde336dc2 to your computer and use it in GitHub Desktop.
Save ElectricCoffee/2eb06fcf996ea8fcf6bc19fdde336dc2 to your computer and use it in GitHub Desktop.
Simple vigenere ciphering script for the hell of it.
// modulo operation that behaves correctly with negative numbers
function mod(n, m) {
return ((n % m) + m) % m;
}
// converts a character to its digit representation
// same as indexOf, but more succinct
function toDigit(char, alphabet) {
return alphabet.indexOf(char)
}
// converts a digit representation to its character
// same as indexing, but more succinct
function fromDigit(num, alphabet) {
return alphabet[num]
}
// strips all the spaces from a string and turns it upper case
function prepareString(string) {
return string.replace(/ /g, "").toUpperCase()
}
// generates a key of the correct length based on the input
// does not ignore spaces
function prepareKey(key, sentence) {
key = key.toUpperCase()
var keylen = key.length, senlen = sentence.length
if (keylen >= senlen) {
return key.substring(0, senlen)
} else {
return prepareKey(key + key, sentence)
}
}
// encrypts a message based on a key, a sentence to be encrypted, and an alphabet
// TODO: refactor later
function encryptMessage(key, sentence, alphabet) {
var sen = prepareString(sentence)
var key = prepareKey(key, sen)
var alphalen = alphabet.length
var cipher = ""
var cipherFinal = ""
// encrypt the text
for (var i = 0; i < sen.length; i++) {
var crypt = mod(toDigit(sen[i], alphabet) + toDigit(key[i], alphabet), alphalen)
cipher += fromDigit(crypt, alphabet)
}
// re-introduce the spaces
for (var i = 0, j = 0; j < sentence.length; i++, j++) {
if (sentence[j] === ' ') {
cipherFinal += ' '
j++
}
cipherFinal += cipher[i]
}
return cipherFinal
}
// decrypts a message based on a key, a sentence to be encrypted, and an alphabet
// TODO: refactor later
function decryptMessage(key, cipher, alphabet) {
var cip = prepareString(cipher)
var key = prepareKey(key, cip)
var alphalen = alphabet.length
var sentence = ""
var sentenceFinal = ""
for (var i = 0; i < cip.length; i++) {
var sen = mod(toDigit(cip[i], alphabet) - toDigit(key[i], alphabet), alphalen)
sentence += fromDigit(sen, alphabet)
}
for (var i = 0, j = 0; j < cipher.length; i++, j++) {
if (cipher[j] === ' ') {
sentenceFinal += ' '
j++
}
sentenceFinal += sentence[i]
}
return sentenceFinal
}
// class representation (unnecessary, but nice to have)
function Vigenere(alphabet, key) {
var self = this
self.alphabet = alphabet.toUpperCase()
self.key = key
self.encrypt = function(sentence) {
return encryptMessage(self.key, sentence, self.alphabet)
}
self.decrypt = function(cipher) {
return decryptMessage(self.key, cipher, self.alphabet)
}
}
var vig = new Vigenere("abcdefghijklmnopqrstuvwxyzæøå", "bananer")
console.log(vig.encrypt("de er her")) // produces EE RR UIF
console.log(vig.decrypt("ee rr uif")) // produces DE ER HER
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment