1
0
mirror of synced 2024-11-28 16:40:49 +01:00

Converted substitute operation, added tests & moved to OperationError

This commit is contained in:
Matt C 2018-05-11 16:32:19 +01:00
parent 350d10d98b
commit 2d6a56343b
8 changed files with 125 additions and 12 deletions

View File

@ -6,6 +6,7 @@
* @license Apache-2.0
*
*/
import OperationError from "../errors/OperationError";
/**
* Affine Cipher Encode operation.
@ -22,7 +23,7 @@ export function affineEncode(input, args) {
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.";
throw new OperationError("The values of a and b can only be integers.");
}
for (let i = 0; i < input.length; i++) {

View File

@ -6,6 +6,7 @@
import Operation from "../Operation";
import Utils from "../Utils";
import OperationError from "../errors/OperationError";
/**
* Affine Cipher Decode operation
@ -50,11 +51,11 @@ class AffineCipherDecode extends Operation {
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.";
throw new OperationError("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.";
throw new OperationError("The value of `a` must be coprime to 26.");
}
for (let i = 0; i < input.length; i++) {

View File

@ -6,7 +6,7 @@
import Operation from "../Operation";
import { genPolybiusSquare } from "../lib/Ciphers";
import OperationError from "../errors/OperationError";
/**
* Bifid Cipher Decode operation
*/
@ -48,7 +48,7 @@ class BifidCipherDecode extends Operation {
trans = "";
if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)
return "The key must consist only of letters in the English alphabet";
throw new OperationError("The key must consist only of letters in the English alphabet");
const polybius = genPolybiusSquare(keywordStr);

View File

@ -5,6 +5,7 @@
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
import { genPolybiusSquare } from "../lib/Ciphers";
/**
@ -50,7 +51,7 @@ class BifidCipherEncode extends Operation {
if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)
return "The key must consist only of letters in the English alphabet";
throw new OperationError("The key must consist only of letters in the English alphabet");
const polybius = genPolybiusSquare(keywordStr);

View File

@ -0,0 +1,65 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation";
import Utils from "../Utils";
/**
* Substitute operation
*/
class Substitute extends Operation {
/**
* Substitute constructor
*/
constructor() {
super();
this.name = "Substitute";
this.module = "Ciphers";
this.description = "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.<br><br>Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.<br><br>Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either <code>\n</code> or <code>\x0a</code>.<br><br>Byte ranges can be specified using a hyphen. For example, the sequence <code>0123456789</code> can be written as <code>0-9</code>.";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Plaintext",
"type": "binaryString",
"value": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
},
{
"name": "Ciphertext",
"type": "binaryString",
"value": "XYZABCDEFGHIJKLMNOPQRSTUVW"
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const plaintext = Utils.expandAlphRange(args[0]).join(""),
ciphertext = Utils.expandAlphRange(args[1]).join("");
let output = "",
index = -1;
if (plaintext.length !== ciphertext.length) {
output = "Warning: Plaintext and Ciphertext lengths differ\n\n";
}
for (let i = 0; i < input.length; i++) {
index = plaintext.indexOf(input[i]);
output += index > -1 && index < ciphertext.length ? ciphertext[index] : input[i];
}
return output;
}
}
export default Substitute;

View File

@ -5,7 +5,7 @@
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/**
* Vigenère Decode operation
*/
@ -45,8 +45,8 @@ class VigenèreDecode extends Operation {
msgIndex,
chr;
if (!key) return "No key entered";
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
if (!key) throw new OperationError("No key entered");
if (!/^[a-zA-Z]+$/.test(key)) throw new OperationError("The key must consist only of letters");
for (let i = 0; i < input.length; i++) {
if (alphabet.indexOf(input[i]) >= 0) {

View File

@ -5,6 +5,7 @@
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/**
* Vigenère Encode operation
@ -45,8 +46,8 @@ class VigenèreEncode extends Operation {
msgIndex,
chr;
if (!key) return "No key entered";
if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters";
if (!key) throw new OperationError("No key entered");
if (!/^[a-zA-Z]+$/.test(key)) throw new OperationError("The key must consist only of letters");
for (let i = 0; i < input.length; i++) {
if (alphabet.indexOf(input[i]) >= 0) {

View File

@ -3,7 +3,7 @@
*
* @author Matt C [matt@artemisbot.uk]
* @author n1474335 [n1474335@gmail.com]
*
*
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
@ -308,4 +308,48 @@ TestRegister.addTests([
}
],
},
{
name: "Substitute: no pt/ct",
input: "flee at once. we are discovered!",
expectedOutput: "flee at once. we are discovered!",
recipeConfig: [
{
"op": "Substitute",
"args": ["", ""]
}
],
},
{
name: "Substitute: no input",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "Substitute",
"args": ["abcdefghijklmnopqrstuvwxyz", "zebrascdfghijklmnopqtuvwxy"]
}
],
},
{
name: "Substitute: uneven pt/ct",
input: "flee at once. we are discovered!",
expectedOutput: "Warning: Plaintext and Ciphertext lengths differ\n\nsiaa zq lkba. va zoa rfpbluaoar!",
recipeConfig: [
{
"op": "Substitute",
"args": ["abcdefghijklmnopqrstuvwxyz", "zebrascdfghijklmnopqtuvwx"]
}
],
},
{
name: "Substitute: normal",
input: "flee at once. we are discovered!",
expectedOutput: "siaa zq lkba. va zoa rfpbluaoar!",
recipeConfig: [
{
"op": "Substitute",
"args": ["abcdefghijklmnopqrstuvwxyz", "zebrascdfghijklmnopqtuvwxy"]
}
],
},
]);