mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 14:56:19 -04:00
104 lines
2.9 KiB
JavaScript
104 lines
2.9 KiB
JavaScript
![]() |
/**
|
||
|
* @author Matt C [matt@artemisbot.uk]
|
||
|
* @copyright Crown Copyright 2018
|
||
|
* @license Apache-2.0
|
||
|
*/
|
||
|
|
||
|
import Operation from "../Operation";
|
||
|
import Utils from "../Utils";
|
||
|
|
||
|
/**
|
||
|
* Affine Cipher Decode operation
|
||
|
*/
|
||
|
class AffineCipherDecode extends Operation {
|
||
|
|
||
|
/**
|
||
|
* AffineCipherDecode constructor
|
||
|
*/
|
||
|
constructor() {
|
||
|
super();
|
||
|
|
||
|
this.name = "Affine Cipher Decode";
|
||
|
this.module = "Ciphers";
|
||
|
this.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.";
|
||
|
this.inputType = "string";
|
||
|
this.outputType = "string";
|
||
|
this.args = [
|
||
|
{
|
||
|
"name": "a",
|
||
|
"type": "number",
|
||
|
"value": 1
|
||
|
},
|
||
|
{
|
||
|
"name": "b",
|
||
|
"type": "number",
|
||
|
"value": 0
|
||
|
}
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {string} input
|
||
|
* @param {Object[]} args
|
||
|
* @returns {string}
|
||
|
*/
|
||
|
run(input, args) {
|
||
|
const alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||
|
a = args[0],
|
||
|
b = args[1],
|
||
|
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)) {
|
||
|
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.";
|
||
|
}
|
||
|
|
||
|
for (let 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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Highlight Affine Cipher Decode
|
||
|
*
|
||
|
* @param {Object[]} pos
|
||
|
* @param {number} pos[].start
|
||
|
* @param {number} pos[].end
|
||
|
* @param {Object[]} args
|
||
|
* @returns {Object[]} pos
|
||
|
*/
|
||
|
highlight(pos, args) {
|
||
|
return pos;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Highlight Affine Cipher Decode in reverse
|
||
|
*
|
||
|
* @param {Object[]} pos
|
||
|
* @param {number} pos[].start
|
||
|
* @param {number} pos[].end
|
||
|
* @param {Object[]} args
|
||
|
* @returns {Object[]} pos
|
||
|
*/
|
||
|
highlightReverse(pos, args) {
|
||
|
return pos;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export default AffineCipherDecode;
|