1
0
mirror of synced 2024-11-16 03:03:22 +01:00

Added tests, removed debug

This commit is contained in:
VirtualColossus 2019-12-04 22:43:22 +00:00
parent a387db6109
commit ccdd2af8be
4 changed files with 34 additions and 56 deletions

View File

@ -110,7 +110,8 @@
"Bombe", "Bombe",
"Multiple Bombe", "Multiple Bombe",
"Typex", "Typex",
"Lorenz" "Lorenz",
"Colossus"
] ]
}, },
{ {

View File

@ -143,14 +143,11 @@ export class ColossusComputer {
this.Xptr = [this.rotorPtrs.X1, this.rotorPtrs.X2, this.rotorPtrs.X3, this.rotorPtrs.X4, this.rotorPtrs.X5]; this.Xptr = [this.rotorPtrs.X1, this.rotorPtrs.X2, this.rotorPtrs.X3, this.rotorPtrs.X4, this.rotorPtrs.X5];
this.Mptr = [this.rotorPtrs.M37, this.rotorPtrs.M61]; this.Mptr = [this.rotorPtrs.M37, this.rotorPtrs.M61];
this.Sptr = [this.rotorPtrs.S1, this.rotorPtrs.S2, this.rotorPtrs.S3, this.rotorPtrs.S4, this.rotorPtrs.S5]; this.Sptr = [this.rotorPtrs.S1, this.rotorPtrs.S2, this.rotorPtrs.S3, this.rotorPtrs.S4, this.rotorPtrs.S5];
// console.log(this.Xptr);
// Run full loop of all character on the input tape (Z) // Run full loop of all character on the input tape (Z)
for (let i=0; i<this.ciphertext.length; i++) { for (let i=0; i<this.ciphertext.length; i++) {
charZin = this.ciphertext.charAt(i); charZin = this.ciphertext.charAt(i);
// console.log('reading tape char #'+i+' : '+charZin);
// Firstly, we check what inputs are specified on the Q-bus input switches // Firstly, we check what inputs are specified on the Q-bus input switches
this.getQbusInputs(charZin); this.getQbusInputs(charZin);
@ -158,13 +155,13 @@ export class ColossusComputer {
* Pattern conditions on individual impulses. Matching patterns of bits on the Q bus. * Pattern conditions on individual impulses. Matching patterns of bits on the Q bus.
* This is the top section on Colussus K rack - the Q bus programming switches * This is the top section on Colussus K rack - the Q bus programming switches
*/ */
this.runQbusProcessingConditional(); const tmpcnt = this.runQbusProcessingConditional();
/* /*
* Addition of impulses. * Addition of impulses.
* This is the bottom section of Colossus K rack. * This is the bottom section of Colossus K rack.
*/ */
this.runQbusProcessingAddition(); this.runQbusProcessingAddition(tmpcnt);
// Store Z bit impulse 5 two back required for P5 limitation // Store Z bit impulse 5 two back required for P5 limitation
this.P5Zbit[1] = this.P5Zbit[0]; this.P5Zbit[1] = this.P5Zbit[0];
@ -191,14 +188,14 @@ export class ColossusComputer {
// Get Chi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain) // Get Chi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain)
let X5bPtr=this.Xptr[4]-1; let X5bPtr=this.Xptr[4]-1;
if (X5bPtr==0) X5bPtr=ROTOR_SIZES.X5; if (X5bPtr===0) X5bPtr=ROTOR_SIZES.X5;
X5bPtr=X5bPtr-1; X5bPtr=X5bPtr-1;
if (X5bPtr==0) X5bPtr=ROTOR_SIZES.X5; if (X5bPtr===0) X5bPtr=ROTOR_SIZES.X5;
// Get Psi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain) // Get Psi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain)
let S5bPtr=this.Sptr[4]-1; let S5bPtr=this.Sptr[4]-1;
if (S5bPtr==0) S5bPtr=ROTOR_SIZES.S5; if (S5bPtr===0) S5bPtr=ROTOR_SIZES.S5;
S5bPtr=S5bPtr-1; S5bPtr=S5bPtr-1;
if (S5bPtr==0) S5bPtr=ROTOR_SIZES.S5; if (S5bPtr===0) S5bPtr=ROTOR_SIZES.S5;
const x2sw = this.limitations.X2; const x2sw = this.limitations.X2;
const s1sw = this.limitations.S1; const s1sw = this.limitations.S1;
@ -217,8 +214,6 @@ export class ColossusComputer {
lim = lim ^ p5lim; lim = lim ^ p5lim;
} }
// console.log(this.Mptr);
// console.log(this.rings.M[2]);
const basicmotor = this.rings.M[2][this.Mptr[0]-1]; const basicmotor = this.rings.M[2][this.Mptr[0]-1];
this.totalmotor = basicmotor; this.totalmotor = basicmotor;
@ -230,8 +225,6 @@ export class ColossusComputer {
} }
} }
// console.log('BM='+basicmotor+', TM='+this.totalmotor);
// Step Chi rotors // Step Chi rotors
for (let r=0; r<5; r++) { for (let r=0; r<5; r++) {
this.Xptr[r]++; this.Xptr[r]++;
@ -239,7 +232,6 @@ export class ColossusComputer {
} }
if (this.totalmotor) { if (this.totalmotor) {
// console.log('step Psi');
// Step Psi rotors // Step Psi rotors
for (let r=0; r<5; r++) { for (let r=0; r<5; r++) {
this.Sptr[r]++; this.Sptr[r]++;
@ -263,81 +255,56 @@ export class ColossusComputer {
getQbusInputs(charZin) { getQbusInputs(charZin) {
// Zbits - the bits from the current character from the cipher tape. // Zbits - the bits from the current character from the cipher tape.
this.Zbits = this.ITAlookup[charZin].split(""); this.Zbits = this.ITAlookup[charZin].split("");
// console.log('Zbits = '+this.Zbits);
if (this.qbusin.Z === "Z") { if (this.qbusin.Z === "Z") {
// direct Z // direct Z
this.Qbits = this.Zbits; this.Qbits = this.Zbits;
// console.log('direct Z: Qbits = '+this.Qbits);
} else if (this.qbusin.Z === "ΔZ") { } else if (this.qbusin.Z === "ΔZ") {
// delta Z, the Bitwise XOR of this character Zbits + last character Zbits // delta Z, the Bitwise XOR of this character Zbits + last character Zbits
for (let b=0;b<5;b++) { for (let b=0;b<5;b++) {
this.Qbits[b] = this.Zbits[b] ^ this.ZbitsOneBack[b]; this.Qbits[b] = this.Zbits[b] ^ this.ZbitsOneBack[b];
} }
// console.log('delta Z: Qbits = '+this.Qbits);
} }
this.ZbitsOneBack = this.Zbits.slice(); // copy value of object, not reference this.ZbitsOneBack = this.Zbits.slice(); // copy value of object, not reference
// console.log('Zin::Q bus now '+this.Qbits+'['+this.ReverseITAlookup[this.Qbits.join("")]+']');
// Xbits - the current Chi wheel bits // Xbits - the current Chi wheel bits
// console.log(this.rings.X);
// console.log('Xptr = '+this.Xptr);
for (let b=0;b<5;b++) { for (let b=0;b<5;b++) {
this.Xbits[b] = this.rings.X[b+1][this.Xptr[b]-1]; this.Xbits[b] = this.rings.X[b+1][this.Xptr[b]-1];
} }
if (this.qbusin.Chi !== "") { if (this.qbusin.Chi !== "") {
// console.log('X Bits '+this.Xbits+'['+this.ReverseITAlookup[this.Xbits.join("")]+']');
// console.log('X Char = ' + this.ReverseITAlookup[this.Xbits.join("")]);
if (this.qbusin.Chi === "Χ") { if (this.qbusin.Chi === "Χ") {
// direct X added to Qbits // direct X added to Qbits
for (let b=0;b<5;b++) { for (let b=0;b<5;b++) {
this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b]; this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b];
} }
// console.log('direct X: Qbits = '+this.Qbits);
} else if (this.qbusin.Chi === "ΔΧ") { } else if (this.qbusin.Chi === "ΔΧ") {
// delta X // delta X
for (let b=0;b<5;b++) { for (let b=0;b<5;b++) {
this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b]; this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b];
this.Qbits[b] = this.Qbits[b] ^ this.XbitsOneBack[b]; this.Qbits[b] = this.Qbits[b] ^ this.XbitsOneBack[b];
} }
// console.log('delta X: Xbits = '+this.Xbits+' Xbits-1 = '+this.XbitsOneBack);
// console.log('delta X: Qbits = '+this.Qbits);
} }
} }
this.XbitsOneBack = this.Xbits.slice(); this.XbitsOneBack = this.Xbits.slice();
// console.log('setting XbitsOneBack to '+this.Xbits);
// console.log('Zin+Xin::Q bus now '+this.Qbits+'['+this.ReverseITAlookup[this.Qbits.join("")]+']');
// Sbits - the current Psi wheel bits // Sbits - the current Psi wheel bits
// console.log(this.rings.S);
// console.log('Sptr = '+this.Sptr);
for (let b=0;b<5;b++) { for (let b=0;b<5;b++) {
this.Sbits[b] = this.rings.S[b+1][this.Sptr[b]-1]; this.Sbits[b] = this.rings.S[b+1][this.Sptr[b]-1];
} }
if (this.qbusin.Psi !== "") { if (this.qbusin.Psi !== "") {
// console.log('S Bits '+this.Sbits+'['+this.ReverseITAlookup[this.Sbits.join("")]+']');
// console.log('S Char = ' + this.ReverseITAlookup[this.Sbits.join("")]);
if (this.qbusin.Psi === "Ψ") { if (this.qbusin.Psi === "Ψ") {
// direct S added to Qbits // direct S added to Qbits
for (let b=0;b<5;b++) { for (let b=0;b<5;b++) {
this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b]; this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b];
} }
// console.log('direct S: Qbits = '+this.Qbits);
} else if (this.qbusin.Psi === "ΔΨ") { } else if (this.qbusin.Psi === "ΔΨ") {
// delta S // delta S
for (let b=0;b<5;b++) { for (let b=0;b<5;b++) {
this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b]; this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b];
this.Qbits[b] = this.Qbits[b] ^ this.SbitsOneBack[b]; this.Qbits[b] = this.Qbits[b] ^ this.SbitsOneBack[b];
} }
// console.log('delta S: Qbits = '+this.Qbits);
} }
} }
this.SbitsOneBack = this.Sbits.slice(); this.SbitsOneBack = this.Sbits.slice();
// console.log('Q bus now '+this.Qbits+'['+this.ReverseITAlookup[this.Qbits.join("")]+']');
} }
/** /**
@ -372,21 +339,21 @@ export class ColossusComputer {
// Negate the whole column, this allows A OR B by doing NOT(NOT A AND NOT B) // Negate the whole column, this allows A OR B by doing NOT(NOT A AND NOT B)
for (let c=0;c<5;c++) { for (let c=0;c<5;c++) {
if (this.qbusswitches.condNegateAll && cnt[c] !== -1) cnt[c] = !cnt[c]; if (this.qbusswitches.condNegateAll && cnt[c] !== -1) cnt[c] = !cnt[c];
if (this.qbusswitches.totalMotor === "" || (this.qbusswitches.totalMotor === "x" && this.totalmotor === 0) || (this.qbusswitches.totalMotor === "." && this.totalmotor === 1)) {
if (cnt[c] === true) this.allCounters[c]++;
} }
} return cnt;
} }
/** /**
* Addition of impulses Q bus section * Addition of impulses Q bus section
*/ */
runQbusProcessingAddition() { runQbusProcessingAddition(cnt) {
const row = this.qbusswitches.addition[0]; const row = this.qbusswitches.addition[0];
const Qswitch = row.Qswitches.slice(); const Qswitch = row.Qswitches.slice();
// To save making the arguments of this operation any larger, limiting addition counter to first one only
// Colossus could actually add into any of the five counters.
if (row.C1) { if (row.C1) {
let addition = 0; let addition = 0;
for (let s=0;s<5;s++) { for (let s=0;s<5;s++) {
@ -397,10 +364,24 @@ export class ColossusComputer {
} }
const equals = (row.Equals===""?-1:(row.Equals==="."?0:1)); const equals = (row.Equals===""?-1:(row.Equals==="."?0:1));
if (addition === equals) { if (addition === equals) {
this.allCounters[0]++; // AND with conditional rows to get final result
if (cnt[0] === -1) cnt[0] = true;
} else {
cnt[0] = false;
} }
} }
// console.log("counter1="+this.allCounters[0]);
// Final check, check for addition section negate
// then, if any column set, from top to bottom of rack, add to counter.
for (let c=0;c<5;c++) {
if (this.qbusswitches.addNegateAll && cnt[c] !== -1) cnt[c] = !cnt[c];
if (this.qbusswitches.totalMotor === "" || (this.qbusswitches.totalMotor === "x" && this.totalmotor === 0) || (this.qbusswitches.totalMotor === "." && this.totalmotor === 1)) {
if (cnt[c] === true) this.allCounters[c]++;
}
}
} }
/** /**

View File

@ -17,13 +17,13 @@ import { SWITCHES, VALID_ITA2 } from "../lib/Lorenz.mjs";
class Colossus extends Operation { class Colossus extends Operation {
/** /**
* Lorenz constructor * Colossus constructor
*/ */
constructor() { constructor() {
super(); super();
this.name = "Colossus"; this.name = "Colossus";
this.module = "Bletchley"; this.module = "Bletchley";
this.description = "Colossus ... "; this.description = "Colossus is the name of the world's first electronic computer. Ten computers were designed by Tommy Flowers and built at the Post Office Research Labs at Dollis Hill in 1943 during World War 2. They assisted with the breaking of the German Lorenz cipher attachment, a machine created to encipher communications between Hitler and his generals on the front lines.<br><br>To learn more, Virtual Colossus, an online, browser based simulation of a Colossus computer is available at <a href='https://virtualcolossus.co.uk' target='_blank'>https://virtualcolossus.co.uk</a>.<br><br>A more detailed description of this operation can be found <a href='https://github.com/VirtualColossus/CyberChef/wiki/Colossus' target='_blank'>here</a>.";
this.infoURL = "https://wikipedia.org/wiki/Colossus_computer"; this.infoURL = "https://wikipedia.org/wiki/Colossus_computer";
this.inputType = "string"; this.inputType = "string";
this.outputType = "JSON"; this.outputType = "JSON";
@ -438,8 +438,6 @@ class Colossus extends Operation {
const colossus = new ColossusComputer(input, pattern, qbusin, qbusswitches, control, starts, settotal, limit); const colossus = new ColossusComputer(input, pattern, qbusin, qbusswitches, control, starts, settotal, limit);
const result = colossus.run(); const result = colossus.run();
console.log(result);
return result; return result;
} }
@ -553,9 +551,6 @@ class Colossus extends Operation {
* @returns {html} * @returns {html}
*/ */
present(output) { present(output) {
console.log("output="+ typeof(output));
console.log("counters="+ typeof(output.counters));
let html = "Colossus Printer\n\n"; let html = "Colossus Printer\n\n";
html += output.printout + "\n\n"; html += output.printout + "\n\n";
html += "Colossus Counters\n\n"; html += "Colossus Counters\n\n";

View File

@ -93,6 +93,7 @@ import "./tests/DefangIP.mjs";
import "./tests/ParseUDP.mjs"; import "./tests/ParseUDP.mjs";
import "./tests/AvroToJSON.mjs"; import "./tests/AvroToJSON.mjs";
import "./tests/Lorenz.mjs"; import "./tests/Lorenz.mjs";
import "./tests/Colossus.mjs";
// Cannot test operations that use the File type yet // Cannot test operations that use the File type yet