mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 14:56:19 -04:00
Converted Vignere, added more tests and cleaned stuff up
This commit is contained in:
parent
789ec94eff
commit
6bec68021c
7 changed files with 358 additions and 357 deletions
|
@ -54,7 +54,7 @@ class AffineCipherDecode extends Operation {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.gcd(a, 26) !== 1) {
|
if (Utils.gcd(a, 26) !== 1) {
|
||||||
return "The value of a must be coprime to 26.";
|
return "The value of `a` must be coprime to 26.";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
for (let i = 0; i < input.length; i++) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @author n1474335 [n1474335@gmail.com]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @copyright Crown Copyright 2016
|
* @copyright Crown Copyright 2018
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -47,11 +47,8 @@ class BifidCipherDecode extends Operation {
|
||||||
count = 0,
|
count = 0,
|
||||||
trans = "";
|
trans = "";
|
||||||
|
|
||||||
if (keyword.length > 25)
|
if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)
|
||||||
return "The alphabet keyword must be less than 25 characters.";
|
return "The key must consist only of letters in the English alphabet";
|
||||||
|
|
||||||
if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
|
|
||||||
return "The key must consist only of letters";
|
|
||||||
|
|
||||||
const polybius = genPolybiusSquare(keywordStr);
|
const polybius = genPolybiusSquare(keywordStr);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @author n1474335 [n1474335@gmail.com]
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
* @copyright Crown Copyright 2016
|
* @copyright Crown Copyright 2018
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -48,11 +48,9 @@ class BifidCipherEncode extends Operation {
|
||||||
let output = "",
|
let output = "",
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
if (keyword.length > 25)
|
|
||||||
return "The alphabet keyword must be less than 25 characters.";
|
|
||||||
|
|
||||||
if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
|
if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)
|
||||||
return "The key must consist only of letters";
|
return "The key must consist only of letters in the English alphabet";
|
||||||
|
|
||||||
const polybius = genPolybiusSquare(keywordStr);
|
const polybius = genPolybiusSquare(keywordStr);
|
||||||
|
|
||||||
|
|
101
src/core/operations/VigenèreDecode.mjs
Normal file
101
src/core/operations/VigenèreDecode.mjs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vigenère Decode operation
|
||||||
|
*/
|
||||||
|
class VigenèreDecode extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VigenèreDecode constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Vigenère Decode";
|
||||||
|
this.module = "Ciphers";
|
||||||
|
this.description = "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Key",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||||
|
key = args[0].toLowerCase();
|
||||||
|
let output = "",
|
||||||
|
fail = 0,
|
||||||
|
keyIndex,
|
||||||
|
msgIndex,
|
||||||
|
chr;
|
||||||
|
|
||||||
|
if (!key) return "No key entered";
|
||||||
|
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
|
||||||
|
|
||||||
|
for (let i = 0; i < input.length; i++) {
|
||||||
|
if (alphabet.indexOf(input[i]) >= 0) {
|
||||||
|
chr = key[(i - fail) % key.length];
|
||||||
|
keyIndex = alphabet.indexOf(chr);
|
||||||
|
msgIndex = alphabet.indexOf(input[i]);
|
||||||
|
// Subtract indexes from each other, add 26 just in case the value is negative,
|
||||||
|
// modulo to remove if neccessary
|
||||||
|
output += alphabet[(msgIndex - keyIndex + alphabet.length) % 26];
|
||||||
|
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
|
||||||
|
chr = key[(i - fail) % key.length].toLowerCase();
|
||||||
|
keyIndex = alphabet.indexOf(chr);
|
||||||
|
msgIndex = alphabet.indexOf(input[i].toLowerCase());
|
||||||
|
output += alphabet[(msgIndex + alphabet.length - keyIndex) % 26].toUpperCase();
|
||||||
|
} else {
|
||||||
|
output += input[i];
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlight Vigenère Decode
|
||||||
|
*
|
||||||
|
* @param {Object[]} pos
|
||||||
|
* @param {number} pos[].start
|
||||||
|
* @param {number} pos[].end
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {Object[]} pos
|
||||||
|
*/
|
||||||
|
highlight(pos, args) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlight Vigenère 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 VigenèreDecode;
|
105
src/core/operations/VigenèreEncode.mjs
Normal file
105
src/core/operations/VigenèreEncode.mjs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vigenère Encode operation
|
||||||
|
*/
|
||||||
|
class VigenèreEncode extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VigenèreEncode constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Vigenère Encode";
|
||||||
|
this.module = "Ciphers";
|
||||||
|
this.description = "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Key",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||||
|
key = args[0].toLowerCase();
|
||||||
|
let output = "",
|
||||||
|
fail = 0,
|
||||||
|
keyIndex,
|
||||||
|
msgIndex,
|
||||||
|
chr;
|
||||||
|
|
||||||
|
if (!key) return "No key entered";
|
||||||
|
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
|
||||||
|
|
||||||
|
for (let i = 0; i < input.length; i++) {
|
||||||
|
if (alphabet.indexOf(input[i]) >= 0) {
|
||||||
|
// Get the corresponding character of key for the current letter, accounting
|
||||||
|
// for chars not in alphabet
|
||||||
|
chr = key[(i - fail) % key.length];
|
||||||
|
// Get the location in the vigenere square of the key char
|
||||||
|
keyIndex = alphabet.indexOf(chr);
|
||||||
|
// Get the location in the vigenere square of the message char
|
||||||
|
msgIndex = alphabet.indexOf(input[i]);
|
||||||
|
// Get the encoded letter by finding the sum of indexes modulo 26 and finding
|
||||||
|
// the letter corresponding to that
|
||||||
|
output += alphabet[(keyIndex + msgIndex) % 26];
|
||||||
|
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
|
||||||
|
chr = key[(i - fail) % key.length].toLowerCase();
|
||||||
|
keyIndex = alphabet.indexOf(chr);
|
||||||
|
msgIndex = alphabet.indexOf(input[i].toLowerCase());
|
||||||
|
output += alphabet[(keyIndex + msgIndex) % 26].toUpperCase();
|
||||||
|
} else {
|
||||||
|
output += input[i];
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlight Vigenère Encode
|
||||||
|
*
|
||||||
|
* @param {Object[]} pos
|
||||||
|
* @param {number} pos[].start
|
||||||
|
* @param {number} pos[].end
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {Object[]} pos
|
||||||
|
*/
|
||||||
|
highlight(pos, args) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlight Vigenère Encode 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 VigenèreEncode;
|
|
@ -569,349 +569,6 @@ DES uses a key length of 8 bytes (64 bits).`;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vigenère Encode operation.
|
|
||||||
*
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runVigenereEnc: function (input, args) {
|
|
||||||
let alphabet = "abcdefghijklmnopqrstuvwxyz",
|
|
||||||
key = args[0].toLowerCase(),
|
|
||||||
output = "",
|
|
||||||
fail = 0,
|
|
||||||
keyIndex,
|
|
||||||
msgIndex,
|
|
||||||
chr;
|
|
||||||
|
|
||||||
if (!key) return "No key entered";
|
|
||||||
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
|
|
||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
|
||||||
if (alphabet.indexOf(input[i]) >= 0) {
|
|
||||||
// Get the corresponding character of key for the current letter, accounting
|
|
||||||
// for chars not in alphabet
|
|
||||||
chr = key[(i - fail) % key.length];
|
|
||||||
// Get the location in the vigenere square of the key char
|
|
||||||
keyIndex = alphabet.indexOf(chr);
|
|
||||||
// Get the location in the vigenere square of the message char
|
|
||||||
msgIndex = alphabet.indexOf(input[i]);
|
|
||||||
// Get the encoded letter by finding the sum of indexes modulo 26 and finding
|
|
||||||
// the letter corresponding to that
|
|
||||||
output += alphabet[(keyIndex + msgIndex) % 26];
|
|
||||||
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
|
|
||||||
chr = key[(i - fail) % key.length].toLowerCase();
|
|
||||||
keyIndex = alphabet.indexOf(chr);
|
|
||||||
msgIndex = alphabet.indexOf(input[i].toLowerCase());
|
|
||||||
output += alphabet[(keyIndex + msgIndex) % 26].toUpperCase();
|
|
||||||
} else {
|
|
||||||
output += input[i];
|
|
||||||
fail++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vigenère Decode operation.
|
|
||||||
*
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runVigenereDec: function (input, args) {
|
|
||||||
let alphabet = "abcdefghijklmnopqrstuvwxyz",
|
|
||||||
key = args[0].toLowerCase(),
|
|
||||||
output = "",
|
|
||||||
fail = 0,
|
|
||||||
keyIndex,
|
|
||||||
msgIndex,
|
|
||||||
chr;
|
|
||||||
|
|
||||||
if (!key) return "No key entered";
|
|
||||||
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
|
|
||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
|
||||||
if (alphabet.indexOf(input[i]) >= 0) {
|
|
||||||
chr = key[(i - fail) % key.length];
|
|
||||||
keyIndex = alphabet.indexOf(chr);
|
|
||||||
msgIndex = alphabet.indexOf(input[i]);
|
|
||||||
// Subtract indexes from each other, add 26 just in case the value is negative,
|
|
||||||
// modulo to remove if neccessary
|
|
||||||
output += alphabet[(msgIndex - keyIndex + alphabet.length) % 26];
|
|
||||||
} else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
|
|
||||||
chr = key[(i - fail) % key.length].toLowerCase();
|
|
||||||
keyIndex = alphabet.indexOf(chr);
|
|
||||||
msgIndex = alphabet.indexOf(input[i].toLowerCase());
|
|
||||||
output += alphabet[(msgIndex + alphabet.length - keyIndex) % 26].toUpperCase();
|
|
||||||
} else {
|
|
||||||
output += input[i];
|
|
||||||
fail++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
AFFINE_A: 1,
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
AFFINE_B: 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Affine Cipher Encode operation.
|
|
||||||
*
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runAffineEnc: function (input, args) {
|
|
||||||
let 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 (let 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 Decode operation.
|
|
||||||
*
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runAffineDec: function (input, args) {
|
|
||||||
let 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 (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;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Atbash Cipher Encode operation.
|
|
||||||
*
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runAtbash: function (input, args) {
|
|
||||||
return Cipher.runAffineEnc(input, [25, 25]);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a polybius square for the given keyword
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} keyword - Must be upper case
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
_genPolybiusSquare: function (keyword) {
|
|
||||||
const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
|
||||||
const polArray = `${keyword}${alpha}`.split("").unique();
|
|
||||||
let polybius = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
polybius[i] = polArray.slice(i*5, i*5 + 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return polybius;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bifid Cipher Encode operation
|
|
||||||
*
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runBifidEnc: function (input, args) {
|
|
||||||
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
|
||||||
keyword = keywordStr.split("").unique(),
|
|
||||||
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
let output = "",
|
|
||||||
xCo = [],
|
|
||||||
yCo = [],
|
|
||||||
structure = [],
|
|
||||||
count = 0;
|
|
||||||
|
|
||||||
if (keyword.length > 25)
|
|
||||||
return "The alphabet keyword must be less than 25 characters.";
|
|
||||||
|
|
||||||
if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
|
|
||||||
return "The key must consist only of letters";
|
|
||||||
|
|
||||||
const polybius = Cipher._genPolybiusSquare(keywordStr);
|
|
||||||
|
|
||||||
input.replace("J", "I").split("").forEach(letter => {
|
|
||||||
let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0,
|
|
||||||
polInd;
|
|
||||||
|
|
||||||
if (alpInd) {
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
|
|
||||||
if (polInd >= 0) {
|
|
||||||
xCo.push(polInd);
|
|
||||||
yCo.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alpha.split("").indexOf(letter) >= 0) {
|
|
||||||
structure.push(true);
|
|
||||||
} else if (alpInd) {
|
|
||||||
structure.push(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
structure.push(letter);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const trans = `${yCo.join("")}${xCo.join("")}`;
|
|
||||||
|
|
||||||
structure.forEach(pos => {
|
|
||||||
if (typeof pos === "boolean") {
|
|
||||||
let coords = trans.substr(2*count, 2).split("");
|
|
||||||
|
|
||||||
output += pos ?
|
|
||||||
polybius[coords[0]][coords[1]] :
|
|
||||||
polybius[coords[0]][coords[1]].toLocaleLowerCase();
|
|
||||||
count++;
|
|
||||||
} else {
|
|
||||||
output += pos;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bifid Cipher Decode operation
|
|
||||||
*
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runBifidDec: function (input, args) {
|
|
||||||
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
|
||||||
keyword = keywordStr.split("").unique(),
|
|
||||||
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
let output = "",
|
|
||||||
structure = [],
|
|
||||||
count = 0,
|
|
||||||
trans = "";
|
|
||||||
|
|
||||||
if (keyword.length > 25)
|
|
||||||
return "The alphabet keyword must be less than 25 characters.";
|
|
||||||
|
|
||||||
if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
|
|
||||||
return "The key must consist only of letters";
|
|
||||||
|
|
||||||
const polybius = Cipher._genPolybiusSquare(keywordStr);
|
|
||||||
|
|
||||||
input.replace("J", "I").split("").forEach((letter) => {
|
|
||||||
let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0,
|
|
||||||
polInd;
|
|
||||||
|
|
||||||
if (alpInd) {
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
|
|
||||||
if (polInd >= 0) {
|
|
||||||
trans += `${i}${polInd}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alpha.split("").indexOf(letter) >= 0) {
|
|
||||||
structure.push(true);
|
|
||||||
} else if (alpInd) {
|
|
||||||
structure.push(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
structure.push(letter);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
structure.forEach(pos => {
|
|
||||||
if (typeof pos === "boolean") {
|
|
||||||
let coords = [trans[count], trans[count+trans.length/2]];
|
|
||||||
|
|
||||||
output += pos ?
|
|
||||||
polybius[coords[0]][coords[1]] :
|
|
||||||
polybius[coords[0]][coords[1]].toLocaleLowerCase();
|
|
||||||
count++;
|
|
||||||
} else {
|
|
||||||
output += pos;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
* @default
|
* @default
|
||||||
|
|
|
@ -22,6 +22,17 @@ TestRegister.addTests([
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Affine Encode: invalid a & b (non-integer)",
|
||||||
|
input: "some keys are shaped as locks. index[me]",
|
||||||
|
expectedOutput: "The values of a and b can only be integers.",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Affine Cipher Encode",
|
||||||
|
args: [0.1, 0.00001]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Affine Encode: no effect",
|
name: "Affine Encode: no effect",
|
||||||
input: "some keys are shaped as locks. index[me]",
|
input: "some keys are shaped as locks. index[me]",
|
||||||
|
@ -55,6 +66,28 @@ TestRegister.addTests([
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Affine Decode: invalid a & b (non-integer)",
|
||||||
|
input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]",
|
||||||
|
expectedOutput: "The values of a and b can only be integers.",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Affine Cipher Decode",
|
||||||
|
args: [0.1, 0.00001]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Affine Decode: invalid a (coprime)",
|
||||||
|
input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]",
|
||||||
|
expectedOutput: "The value of `a` must be coprime to 26.",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Affine Cipher Decode",
|
||||||
|
args: [8, 23]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Affine Decode: no effect",
|
name: "Affine Decode: no effect",
|
||||||
input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]",
|
input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]",
|
||||||
|
@ -121,6 +154,17 @@ TestRegister.addTests([
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Encode: invalid key (non-alphabetic)",
|
||||||
|
input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
|
||||||
|
expectedOutput: "The key must consist only of letters in the English alphabet",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Encode",
|
||||||
|
"args": ["abc123"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Bifid Cipher Encode: normal",
|
name: "Bifid Cipher Encode: normal",
|
||||||
input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
|
input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
|
||||||
|
@ -154,6 +198,17 @@ TestRegister.addTests([
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Bifid Cipher Decode: invalid key (non-alphabetic)",
|
||||||
|
input: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.",
|
||||||
|
expectedOutput: "The key must consist only of letters in the English alphabet",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Bifid Cipher Decode",
|
||||||
|
"args": ["abc123"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Bifid Cipher Decode: normal",
|
name: "Bifid Cipher Decode: normal",
|
||||||
input: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
|
input: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
|
||||||
|
@ -165,4 +220,92 @@ TestRegister.addTests([
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Encode: no input",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Encode",
|
||||||
|
"args": ["nothing"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Encode: no key",
|
||||||
|
input: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID",
|
||||||
|
expectedOutput: "No key entered",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Encode",
|
||||||
|
"args": [""]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Encode: invalid key",
|
||||||
|
input: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID",
|
||||||
|
expectedOutput: "The key must consist only of letters",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Encode",
|
||||||
|
"args": ["abc123"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Encode: normal",
|
||||||
|
input: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID",
|
||||||
|
expectedOutput: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Encode",
|
||||||
|
"args": ["Edward"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Decode: no input",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Decode",
|
||||||
|
"args": ["nothing"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Decode: no key",
|
||||||
|
input: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED",
|
||||||
|
expectedOutput: "No key entered",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Decode",
|
||||||
|
"args": [""]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Decode: invalid key",
|
||||||
|
input: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED",
|
||||||
|
expectedOutput: "The key must consist only of letters",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Decode",
|
||||||
|
"args": ["abc123"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vigenère Decode: normal",
|
||||||
|
input: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED",
|
||||||
|
expectedOutput: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Vigenère Decode",
|
||||||
|
"args": ["Edward"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue