diff --git a/src/core/operations/AffineCipherDecode.mjs b/src/core/operations/AffineCipherDecode.mjs index 78666d10..45316f9a 100644 --- a/src/core/operations/AffineCipherDecode.mjs +++ b/src/core/operations/AffineCipherDecode.mjs @@ -5,8 +5,7 @@ */ import Operation from "../Operation.mjs"; -import Utils from "../Utils.mjs"; -import OperationError from "../errors/OperationError.mjs"; +import { affineDecrypt, affineDecryptInverse, AFFINE_ALPHABETS } from "../lib/Ciphers.mjs"; /** * Affine Cipher Decode operation @@ -36,6 +35,11 @@ class AffineCipherDecode extends Operation { "type": "number", "value": 0 }, + { + "name": "Alphabet", + "type": "editableOption", + "value": AFFINE_ALPHABETS + }, { "name": "Use modular inverse values", "type": "boolean", @@ -52,43 +56,9 @@ class AffineCipherDecode extends Operation { * @throws {OperationError} if a or b values are invalid */ run(input, args) { - const alphabet = "abcdefghijklmnopqrstuvwxyz", - [a, b, useInv] = args, - aModInv = Utils.modInv(a, 26); // Calculates modular inverse of a - let output = ""; - - if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) { - throw new OperationError("The values of a and b can only be integers."); - } - - if (Utils.gcd(a, 26) !== 1) { - throw new OperationError("The value of `a` must be coprime to 26."); - } - - for (let i = 0; i < input.length; i++) { - if (alphabet.indexOf(input[i]) >= 0) { - if (useInv) { - // Uses the affine decode function (y+b)*a % m, where m is the length - // of the alphabet and a,b are modular inverses of the original a,b - output += alphabet[Utils.mod((alphabet.indexOf(input[i]) + b) * a, 26)]; - } else { - // 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) { - if (useInv) { - // Same as above, accounting for uppercase - output += alphabet[Utils.mod((alphabet.indexOf(input[i].toLowerCase()) + b) * a, 26)].toUpperCase(); - } else { - // 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; + const a = args[0], b = args[1], alphabet = args[2], useInverse = args[3]; + if (useInverse) return affineDecryptInverse(input, a, b, alphabet); + else return affineDecrypt(input, a, b, alphabet); } /**