Adds Affine/Atbash Cipher encryption/decryption

- 3 new operations - Affine Encode, Decode and Atbash Cipher
- Added 3 new utils - mod, GCD and modInv
This commit is contained in:
Matt C 2017-02-08 11:51:37 +00:00
parent 35d74980a1
commit 2750be36da
8 changed files with 247 additions and 83 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -66,6 +66,9 @@ var Categories = [
ops: [
"AES Encrypt",
"AES Decrypt",
"Affine Cipher Encode",
"Affine Cipher Decode",
"Atbash Cipher",
"Blowfish Encrypt",
"Blowfish Decrypt",
"DES Encrypt",

View file

@ -1360,6 +1360,55 @@ var OperationConfig = {
}
]
},
"Affine Cipher Encode": {
description: "The affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function (ax + b) % 26, and converted back to a letter.",
run: Cipher.runAffineEnc,
highlight: true,
highlightReverse: true,
inputType: "string",
outputType: "string",
args: [
{
name: "a",
type: "number",
value: Cipher.AFFINE_A
},
{
name: "b",
type: "number",
value: Cipher.AFFINE_B
}
]
},
"Affine Cipher Decode": {
description: "The affine cipher is a type of monoalphabetic substitution cipher. To decrypt, each letter in an alphabet is mapped to its numeric equivalent, decrypted by a mathematical function, and converted back to a letter.",
run: Cipher.runAffineDec,
highlight: true,
highlightReverse: true,
inputType: "string",
outputType: "string",
args: [
{
name: "a",
type: "number",
value: Cipher.AFFINE_A
},
{
name: "b",
type: "number",
value: Cipher.AFFINE_B
}
]
},
"Atbash Cipher": {
description: "Atbash is a mono-alphabetic substitution cipher originally used to encode the Hebrew alphabet. It has been modified here for use with the latin alphabet.",
run: Cipher.runAtbash,
highlight: true,
highlightReverse: true,
inputType: "string",
outputType: "string",
args: []
},
"Rotate right": {
description: "Rotates each byte to the right by the number of bits specified. Currently only supports 8-bit values.",
run: Rotate.runRotr,

View file

@ -927,7 +927,37 @@ var Utils = {
a[key] = b[key];
return a;
},
/**
* Actual modulo function, since % is actually the remainder function in JS
* @author Matt C [matt@artemisbot.pw]
* @param {number} x
* @param {number} y
*/
mod: function (x, y) {
return ((x % y) + y) % y;
},
/**
* Finds GCD of two numbers
* @author Matt C [matt@artemisbot.pw]
* @param {number} x
* @param {number} y
*/
gcd: function(x, y) {
if (!y) {
return x;
}
return Utils.gcd(y, x % y);
},
modInv: function(x, y) {
x %= y;
for (var i = 1; i < y; i++) {
if ((x * i) % 26 === 1) {
return i;
}
}
},
/**
* A mapping of names of delimiter characters to their symbols.

View file

@ -385,7 +385,6 @@ var Cipher = {
return encrypted.ciphertext.toString(Utils.format[args[2]]);
},
/**
* Vigenère Encode operation.
*
@ -475,6 +474,89 @@ var Cipher = {
return output;
},
/**
* @constant
* @default
*/
AFFINE_A: 1,
/**
* @constant
* @default
*/
AFFINE_B: 0,
/**
* Affine Cipher Encode operation.
*
* @author Matt C [matt@artemisbot.pw]
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
runAffineEnc: function (input, args) {
var alphabet = "abcdefghijklmnopqrstuvwxyz",
a = args[0],
b = args[1],
output = "";
if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) return "The values of a and b can only be integers.";
for (var i = 0; i < input.length; i++) {
if (alphabet.indexOf(input[i]) >= 0) {
// Uses the affine function ax+b % m = y (where m is length of the alphabet)
output += alphabet[((a * alphabet.indexOf(input[i])) + b) % 26];
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
// Same as above, accounting for uppercase
output += alphabet[((a * alphabet.indexOf(input[i].toLowerCase())) + b) % 26].toUpperCase();
} else {
// Non-alphabetic characters
output += input[i];
}
}
return output;
},
/**
* Affine Cipher Encode operation.
*
* @author Matt C [matt@artemisbot.pw]
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
runAffineDec: function (input, args) {
var alphabet = "abcdefghijklmnopqrstuvwxyz",
a = args[0],
b = args[1],
output = "",
aModInv;
if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) return "The values of a and b can only be integers.";
if (Utils.gcd(a, 26) !== 1) return "The value of a must be coprime to 26.";
// Calculates modular inverse of a
aModInv = Utils.modInv(a, 26);
for (var i = 0; i < input.length; i++) {
if (alphabet.indexOf(input[i]) >= 0) {
// Uses the affine decode function (y-b * A') % m = x (where m is length of the alphabet and A' is modular inverse)
output += alphabet[Utils.mod((alphabet.indexOf(input[i]) - b) * aModInv, 26)];
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
// Same as above, accounting for uppercase
output += alphabet[Utils.mod((alphabet.indexOf(input[i].toLowerCase()) - b) * aModInv, 26)].toUpperCase();
} else {
// Non-alphabetic characters
output += input[i];
}
}
return output;
},
/**
* Atbash Cipher Encode operation.
*
* @author Matt C [matt@artemisbot.pw]
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
runAtbash: function (input, args) {
return Cipher.runAffineEnc(input, [25, 25]);
},
/**
* @constant

View file

@ -1,9 +1,9 @@
212 source files
115060 lines
211 source files
115224 lines
4.3M size
142 JavaScript source files
105900 lines
106064 lines
3.8M size
83 third party JavaScript source files
@ -11,11 +11,11 @@
3.0M size
59 first party JavaScript source files
19642 lines
740K size
19806 lines
748K size
3.4M uncompressed JavaScript size
3.5M uncompressed JavaScript size
1.9M compressed JavaScript size
15 categories
167 operations
170 operations