mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-21 23:36:16 -04:00
Merge branch 'artemisbot-features/bifid'
This commit is contained in:
commit
51798553e1
9 changed files with 277 additions and 13 deletions
|
@ -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}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
78
test/tests/operations/Cipher.js
Normal file
78
test/tests/operations/Cipher.js
Normal 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"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
Loading…
Add table
Add a link
Reference in a new issue