mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-22 07:46:16 -04:00
Added Bifid Cipher Encode & Decode
Bifid Cipher + Tests
This commit is contained in:
parent
a417a6469c
commit
91c6f682e7
5 changed files with 248 additions and 6 deletions
|
@ -89,6 +89,8 @@ const Categories = [
|
|||
"Vigenère Decode",
|
||||
"To Morse Code",
|
||||
"From Morse Code",
|
||||
"Bifid Cipher Encode",
|
||||
"Bifid Cipher Decode",
|
||||
"Affine Cipher Encode",
|
||||
"Affine Cipher Decode",
|
||||
"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: "Alphabet Key",
|
||||
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: "Alphabet Key",
|
||||
type: "string",
|
||||
value: ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"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.",
|
||||
run: Cipher.runAffineEnc,
|
||||
|
|
|
@ -407,7 +407,7 @@ const Cipher = {
|
|||
/**
|
||||
* Vigenère Encode operation.
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.pw]
|
||||
* @author Matt C [matt@artemisbot.uk]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
|
@ -454,7 +454,7 @@ const Cipher = {
|
|||
/**
|
||||
* Vigenère Decode operation.
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.pw]
|
||||
* @author Matt C [matt@artemisbot.uk]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
|
@ -508,7 +508,7 @@ const Cipher = {
|
|||
/**
|
||||
* Affine Cipher Encode operation.
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.pw]
|
||||
* @author Matt C [matt@artemisbot.uk]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @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 {Object[]} args
|
||||
* @returns {string}
|
||||
|
@ -584,7 +584,7 @@ const Cipher = {
|
|||
/**
|
||||
* Atbash Cipher Encode operation.
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.pw]
|
||||
* @author Matt C [matt@artemisbot.uk]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
|
@ -593,6 +593,137 @@ const Cipher = {
|
|||
return Cipher.runAffineEnc(input, [25, 25]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates a polybius square for the given keyword
|
||||
*
|
||||
* @author Matt C [matt@artemisbot.uk]
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
genPolybiusSquare: function (keyword) {
|
||||
const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
||||
let polybius = [],
|
||||
polString = "";
|
||||
keyword.split("").unique().forEach(letter => {
|
||||
polString += letter;
|
||||
});
|
||||
polString = `${polString}${alpha}`.split("").unique().join("");
|
||||
for (let i = 0; i < 5; i++) {
|
||||
polybius[i] = polString.substr(i*5, 5).split("");
|
||||
}
|
||||
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 keyword = args[0].toUpperCase().replace("J", "I"),
|
||||
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
||||
let output = "",
|
||||
xCo = [],
|
||||
yCo = [],
|
||||
structure = [],
|
||||
count = 0,
|
||||
trans;
|
||||
if (keyword.split("").unique().length > 25) return "The alphabet keyword must be less than 25 characters.";
|
||||
if (!/^[a-zA-Z]+$/.test(keyword) && keyword.split("").unique().length > 0) return "The key must consist only of letters";
|
||||
const polybius = Cipher.genPolybiusSquare(keyword);
|
||||
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);
|
||||
}
|
||||
});
|
||||
trans = `${yCo.join("")}${xCo.join("")}`;
|
||||
structure.forEach(pos => {
|
||||
if (typeof pos === "boolean") {
|
||||
let coords = trans.substr(2*count, 2).split("");
|
||||
if (pos) {
|
||||
output += polybius[coords[0]][coords[1]];
|
||||
} else {
|
||||
output += 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 keyword = args[0].toUpperCase().replace("J", "I"),
|
||||
alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
|
||||
let output = "",
|
||||
structure = [],
|
||||
count = 0,
|
||||
trans = "";
|
||||
if (keyword.split("").unique().length > 25) return "The alphabet keyword must be less than 25 characters.";
|
||||
if (!/^[a-zA-Z]+$/.test(keyword) && keyword.split("").unique().length > 0) return "The key must consist only of letters";
|
||||
const polybius = Cipher.genPolybiusSquare(keyword);
|
||||
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]];
|
||||
if (pos) {
|
||||
output += polybius[coords[0]][coords[1]];
|
||||
} else {
|
||||
output += polybius[coords[0]][coords[1]].toLocaleLowerCase();
|
||||
}
|
||||
count++;
|
||||
} else {
|
||||
output += pos;
|
||||
}
|
||||
});
|
||||
return output;
|
||||
},
|
||||
|
||||
/**
|
||||
* @constant
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue