Add De Bruijn Operation
This commit is contained in:
parent
8148c1a8a8
commit
1f09c03d48
@ -370,6 +370,7 @@
|
|||||||
"Chi Square",
|
"Chi Square",
|
||||||
"Disassemble x86",
|
"Disassemble x86",
|
||||||
"Pseudo-Random Number Generator",
|
"Pseudo-Random Number Generator",
|
||||||
|
"Generate De Bruijn Sequence",
|
||||||
"Generate UUID",
|
"Generate UUID",
|
||||||
"Generate TOTP",
|
"Generate TOTP",
|
||||||
"Generate HOTP",
|
"Generate HOTP",
|
||||||
|
87
src/core/operations/GenerateDeBruijnSequence.mjs
Normal file
87
src/core/operations/GenerateDeBruijnSequence.mjs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* @author gchq77703 [gchq77703@gchq.gov.uk]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate De Bruijn Sequence operation
|
||||||
|
*/
|
||||||
|
class GenerateDeBruijnSequence extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GenerateDeBruijnSequence constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Generate De Bruijn Sequence";
|
||||||
|
this.module = "Default";
|
||||||
|
this.description = "Generates rolling keycode combinations given a certain alphabet size and key length.";
|
||||||
|
this.infoURL = "https://wikipedia.org/wiki/De_Bruijn_sequence";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Alphabet size (k)",
|
||||||
|
type: "number",
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Key length (n)",
|
||||||
|
type: "number",
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const [k, n] = args;
|
||||||
|
|
||||||
|
if (k < 2 || k > 9) {
|
||||||
|
throw new OperationError("Invalid alphabet size, required to be between 2 and 9 (inclusive).");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < 2) {
|
||||||
|
throw new OperationError("Invalid key length, required to be at least 2.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.pow(k, n) > 50000) {
|
||||||
|
throw new OperationError("Too many permutations, please reduce k^n to under 50,000.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const a = [];
|
||||||
|
for (let i = 0; i < k * n; i++) a.push(0);
|
||||||
|
|
||||||
|
const sequence = [];
|
||||||
|
|
||||||
|
(function db(t = 1, p = 1) {
|
||||||
|
if (t > n) {
|
||||||
|
if (n % p !== 0) return;
|
||||||
|
for (let j = 1; j <= p; j++) {
|
||||||
|
sequence.push(a[j]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[t] = a[t - p];
|
||||||
|
db(t + 1, p);
|
||||||
|
for (let j = a[t - p] + 1; j < k; j++) {
|
||||||
|
a[t] = j;
|
||||||
|
db(t + 1, t);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
return sequence.join("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GenerateDeBruijnSequence;
|
@ -45,6 +45,7 @@ import "./tests/DateTime";
|
|||||||
import "./tests/ExtractEmailAddresses";
|
import "./tests/ExtractEmailAddresses";
|
||||||
import "./tests/Fork";
|
import "./tests/Fork";
|
||||||
import "./tests/FromDecimal";
|
import "./tests/FromDecimal";
|
||||||
|
import "./tests/GenerateDeBruijnSequence";
|
||||||
import "./tests/Hash";
|
import "./tests/Hash";
|
||||||
import "./tests/HaversineDistance";
|
import "./tests/HaversineDistance";
|
||||||
import "./tests/Hexdump";
|
import "./tests/Hexdump";
|
||||||
|
33
tests/operations/tests/GenerateDeBruijnSequence.mjs
Normal file
33
tests/operations/tests/GenerateDeBruijnSequence.mjs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* De Brujin Sequence tests.
|
||||||
|
*
|
||||||
|
* @author gchq77703 [gchq77703@gchq.gov.uk]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../TestRegister";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "Small Sequence",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "00010111",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Generate De Bruijn Sequence",
|
||||||
|
"args": [2, 3]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Long Sequence",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "0000010000200003000110001200013000210002200023000310003200033001010010200103001110011200113001210012200123001310013200133002010020200203002110021200213002210022200223002310023200233003010030200303003110031200313003210032200323003310033200333010110101201013010210102201023010310103201033011020110301111011120111301121011220112301131011320113301202012030121101212012130122101222012230123101232012330130201303013110131201313013210132201323013310133201333020210202202023020310203202033021030211102112021130212102122021230213102132021330220302211022120221302221022220222302231022320223302303023110231202313023210232202323023310233202333030310303203033031110311203113031210312203123031310313203133032110321203213032210322203223032310323203233033110331203313033210332203323033310333203333111112111131112211123111321113311212112131122211223112321123311312113131132211323113321133312122121231213212133122131222212223122321223312313123221232312332123331313213133132221322313232132331332213323133321333322222322233223232233323233233333",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Generate De Bruijn Sequence",
|
||||||
|
"args": [4, 5]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
Loading…
Reference in New Issue
Block a user