Merge branch 'artemisbot-features/bifid'

This commit is contained in:
n1474335 2017-06-28 19:55:19 +01:00
commit 51798553e1
9 changed files with 277 additions and 13 deletions

View File

@ -1050,7 +1050,7 @@ const Utils = {
/** /**
* Actual modulo function, since % is actually the remainder function in JS. * Actual modulo function, since % is actually the remainder function in JS.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
* @returns {number} * @returns {number}
@ -1063,7 +1063,7 @@ const Utils = {
/** /**
* Finds the greatest common divisor of two numbers. * Finds the greatest common divisor of two numbers.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
* @returns {number} * @returns {number}
@ -1079,7 +1079,7 @@ const Utils = {
/** /**
* Finds the modular inverse of two values. * Finds the modular inverse of two values.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
* @returns {number} * @returns {number}

View File

@ -89,6 +89,8 @@ const Categories = [
"Vigenère Decode", "Vigenère Decode",
"To Morse Code", "To Morse Code",
"From Morse Code", "From Morse Code",
"Bifid Cipher Encode",
"Bifid Cipher Decode",
"Affine Cipher Encode", "Affine Cipher Encode",
"Affine Cipher Decode", "Affine Cipher Decode",
"Atbash Cipher", "Atbash Cipher",

View File

@ -1512,6 +1512,36 @@ const OperationConfig = {
} }
] ]
}, },
"Bifid Cipher Encode": {
description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.",
run: Cipher.runBifidEnc,
highlight: true,
highlightReverse: true,
inputType: "string",
outputType: "string",
args: [
{
name: "Keyword",
type: "string",
value: ""
}
]
},
"Bifid Cipher Decode": {
description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.",
run: Cipher.runBifidDec,
highlight: true,
highlightReverse: true,
inputType: "string",
outputType: "string",
args: [
{
name: "Keyword",
type: "string",
value: ""
}
]
},
"Affine Cipher Encode": { "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, <code>(ax + b) % 26</code>, and converted back to a letter.", 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, <code>(ax + b) % 26</code>, and converted back to a letter.",
run: Cipher.runAffineEnc, run: Cipher.runAffineEnc,

View File

@ -58,7 +58,7 @@ const ByteRepr = {
/** /**
* To Octal operation. * To Octal operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {byteArray} input * @param {byteArray} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
@ -72,7 +72,7 @@ const ByteRepr = {
/** /**
* From Octal operation. * From Octal operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {byteArray} * @returns {byteArray}

View File

@ -407,7 +407,7 @@ const Cipher = {
/** /**
* Vigenère Encode operation. * Vigenère Encode operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
@ -454,7 +454,7 @@ const Cipher = {
/** /**
* Vigenère Decode operation. * Vigenère Decode operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
@ -508,7 +508,7 @@ const Cipher = {
/** /**
* Affine Cipher Encode operation. * Affine Cipher Encode operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
@ -540,9 +540,9 @@ const Cipher = {
/** /**
* Affine Cipher Encode operation. * Affine Cipher Decode operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
@ -584,7 +584,7 @@ const Cipher = {
/** /**
* Atbash Cipher Encode operation. * Atbash Cipher Encode operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {string} input * @param {string} input
* @param {Object[]} args * @param {Object[]} args
* @returns {string} * @returns {string}
@ -594,6 +594,159 @@ const Cipher = {
}, },
/**
* 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

View File

@ -135,7 +135,7 @@ const Rotate = {
/** /**
* ROT47 operation. * ROT47 operation.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @param {byteArray} input * @param {byteArray} input
* @param {Object[]} args * @param {Object[]} args
* @returns {byteArray} * @returns {byteArray}

View File

@ -14,6 +14,7 @@ import TestRegister from "./TestRegister.js";
import "./tests/operations/Base58.js"; import "./tests/operations/Base58.js";
import "./tests/operations/ByteRepr.js"; import "./tests/operations/ByteRepr.js";
import "./tests/operations/CharEnc.js"; import "./tests/operations/CharEnc.js";
import "./tests/operations/Cipher.js";
import "./tests/operations/Code.js"; import "./tests/operations/Code.js";
import "./tests/operations/Compress.js"; import "./tests/operations/Compress.js";
import "./tests/operations/DateTime.js"; import "./tests/operations/DateTime.js";

View File

@ -1,7 +1,7 @@
/** /**
* ByteRepr tests. * ByteRepr tests.
* *
* @author Matt C [matt@artemisbot.pw] * @author Matt C [matt@artemisbot.uk]
* @copyright Crown Copyright 2017 * @copyright Crown Copyright 2017
* @license Apache-2.0 * @license Apache-2.0
*/ */

View File

@ -0,0 +1,78 @@
/**
* Cipher tests.
*
* @author Matt C [matt@artemisbot.uk]
*
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister.js";
TestRegister.addTests([
{
name: "Bifid Cipher Encode: no input",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "Bifid Cipher Encode",
"args": ["nothing"]
}
],
},
{
name: "Bifid Cipher Encode: no key",
input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
expectedOutput: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.",
recipeConfig: [
{
"op": "Bifid Cipher Encode",
"args": [""]
}
],
},
{
name: "Bifid Cipher Encode: normal",
input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
expectedOutput: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
recipeConfig: [
{
"op": "Bifid Cipher Encode",
"args": ["Schrodinger"]
}
],
},
{
name: "Bifid Cipher Decode: no input",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "Bifid Cipher Decode",
"args": ["nothing"]
}
],
},
{
name: "Bifid Cipher Decode: no key",
input: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.",
expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
recipeConfig: [
{
"op": "Bifid Cipher Decode",
"args": [""]
}
],
},
{
name: "Bifid Cipher Decode: normal",
input: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
recipeConfig: [
{
"op": "Bifid Cipher Decode",
"args": ["Schrodinger"]
}
],
},
]);