mirror of
https://github.com/gchq/CyberChef.git
synced 2024-11-16 08:58:30 +01:00
Bombe: further optimisation
This commit is contained in:
parent
d94e8c8187
commit
49f5c94a75
1 changed files with 32 additions and 31 deletions
|
@ -158,27 +158,6 @@ class SharedScrambler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the fully cached result, if present.
|
|
||||||
* @param {number} pos - Position of the fast rotor
|
|
||||||
* @param {number} i - Letter
|
|
||||||
* @returns {number|undefined} - undefined if not cached
|
|
||||||
*/
|
|
||||||
fullTransform(pos, i) {
|
|
||||||
return this.higherCache[pos][i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a value to the full result cache.
|
|
||||||
* @param {number} pos - Position of the fast rotor
|
|
||||||
* @param {number} i - Letter
|
|
||||||
* @param {number} val - Transformed letter
|
|
||||||
*/
|
|
||||||
addCache(pos, i, val) {
|
|
||||||
this.higherCache[pos][i] = val;
|
|
||||||
this.higherCache[pos][val] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map a letter through this (partial) scrambler.
|
* Map a letter through this (partial) scrambler.
|
||||||
* @param {number} i - The letter
|
* @param {number} i - The letter
|
||||||
|
@ -209,6 +188,9 @@ class Scrambler {
|
||||||
this.changeRotor(rotor);
|
this.changeRotor(rotor);
|
||||||
this.end1 = end1;
|
this.end1 = end1;
|
||||||
this.end2 = end2;
|
this.end2 = end2;
|
||||||
|
// For efficiency reasons, we pull the relevant shared cache from the baseScrambler into
|
||||||
|
// this object - this saves us a few pointer dereferences
|
||||||
|
this.cache = this.baseScrambler.higherCache[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -233,6 +215,7 @@ class Scrambler {
|
||||||
// simplifies caching the state of the majority of the scramblers. The results are the
|
// simplifies caching the state of the majority of the scramblers. The results are the
|
||||||
// same, just in a slightly different order.
|
// same, just in a slightly different order.
|
||||||
this.rotor.step();
|
this.rotor.step();
|
||||||
|
this.cache = this.baseScrambler.higherCache[this.rotor.pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,14 +226,15 @@ class Scrambler {
|
||||||
*/
|
*/
|
||||||
transform(i) {
|
transform(i) {
|
||||||
let letter = i;
|
let letter = i;
|
||||||
const cached = this.baseScrambler.fullTransform(this.rotor.pos, i);
|
const cached = this.cache[i];
|
||||||
if (cached !== undefined) {
|
if (cached !== undefined) {
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
letter = this.rotor.transform(letter);
|
letter = this.rotor.transform(letter);
|
||||||
letter = this.baseScrambler.transform(letter);
|
letter = this.baseScrambler.transform(letter);
|
||||||
letter = this.rotor.revTransform(letter);
|
letter = this.rotor.revTransform(letter);
|
||||||
this.baseScrambler.addCache(this.rotor.pos, i, letter);
|
this.cache[i] = letter;
|
||||||
|
this.cache[letter] = i;
|
||||||
return letter;
|
return letter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,12 +497,26 @@ export class BombeMachine {
|
||||||
// both.
|
// both.
|
||||||
const idxPair = 26*j + i;
|
const idxPair = 26*j + i;
|
||||||
this.wires[idxPair] = true;
|
this.wires[idxPair] = true;
|
||||||
|
if (i === this.testRegister || j === this.testRegister) {
|
||||||
|
this.energiseCount++;
|
||||||
|
if (this.energiseCount === 26) {
|
||||||
|
// no point continuing, bail out
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let k=0; k<this.scramblers[i].length; k++) {
|
for (let k=0; k<this.scramblers[i].length; k++) {
|
||||||
const scrambler = this.scramblers[i][k];
|
const scrambler = this.scramblers[i][k];
|
||||||
const out = scrambler.transform(j);
|
const out = scrambler.transform(j);
|
||||||
const other = scrambler.getOtherEnd(i);
|
const other = scrambler.getOtherEnd(i);
|
||||||
this.energise(other, out);
|
// Lift the pre-check before the call, to save some function call overhead
|
||||||
|
const otherIdx = 26*other + out;
|
||||||
|
if (!this.wires[otherIdx]) {
|
||||||
|
this.energise(other, out);
|
||||||
|
if (this.energiseCount === 26) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (i === j) {
|
if (i === j) {
|
||||||
return;
|
return;
|
||||||
|
@ -527,7 +525,13 @@ export class BombeMachine {
|
||||||
const scrambler = this.scramblers[j][k];
|
const scrambler = this.scramblers[j][k];
|
||||||
const out = scrambler.transform(i);
|
const out = scrambler.transform(i);
|
||||||
const other = scrambler.getOtherEnd(j);
|
const other = scrambler.getOtherEnd(j);
|
||||||
this.energise(other, out);
|
const otherIdx = 26*other + out;
|
||||||
|
if (!this.wires[otherIdx]) {
|
||||||
|
this.energise(other, out);
|
||||||
|
if (this.energiseCount === 26) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,6 +614,7 @@ export class BombeMachine {
|
||||||
for (let i=0; i<this.wires.length; i++) {
|
for (let i=0; i<this.wires.length; i++) {
|
||||||
this.wires[i] = false;
|
this.wires[i] = false;
|
||||||
}
|
}
|
||||||
|
this.energiseCount = 0;
|
||||||
// Re-energise with the corrected hypothesis
|
// Re-energise with the corrected hypothesis
|
||||||
this.energise(this.testRegister, pair);
|
this.energise(this.testRegister, pair);
|
||||||
}
|
}
|
||||||
|
@ -643,12 +648,7 @@ export class BombeMachine {
|
||||||
*/
|
*/
|
||||||
checkStop() {
|
checkStop() {
|
||||||
// Count the energised outputs
|
// Count the energised outputs
|
||||||
let count = 0;
|
const count = this.energiseCount;
|
||||||
for (let j=26*this.testRegister; j<26*(1+this.testRegister); j++) {
|
|
||||||
if (this.wires[j]) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count === 26) {
|
if (count === 26) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -705,6 +705,7 @@ export class BombeMachine {
|
||||||
for (let i=0; i<this.wires.length; i++) {
|
for (let i=0; i<this.wires.length; i++) {
|
||||||
this.wires[i] = false;
|
this.wires[i] = false;
|
||||||
}
|
}
|
||||||
|
this.energiseCount = 0;
|
||||||
// Energise the test input, follow the current through each scrambler
|
// Energise the test input, follow the current through each scrambler
|
||||||
// (and the diagonal board)
|
// (and the diagonal board)
|
||||||
this.energise(...this.testInput);
|
this.energise(...this.testInput);
|
||||||
|
|
Loading…
Reference in a new issue