From 0f5f20247a87c1ee979c2373834be60c3254397a Mon Sep 17 00:00:00 2001 From: VirtualColossus <48803849+VirtualColossus@users.noreply.github.com> Date: Mon, 25 Mar 2019 13:25:13 +0000 Subject: [PATCH 01/17] Added Lorenz SZ40/42 operation --- src/core/operations/Lorenz.mjs | 606 +++++++++++++++++++++++++++++++++ 1 file changed, 606 insertions(+) create mode 100644 src/core/operations/Lorenz.mjs diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs new file mode 100644 index 000000000..72331727d --- /dev/null +++ b/src/core/operations/Lorenz.mjs @@ -0,0 +1,606 @@ +/** + * Emulation of the Lorenz SZ40/42a/42b cipher attachment. + * + * @author VirtualColossus [martin@virtualcolossus.co.uk] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Lorenz operation + */ +class Lorenz extends Operation { + + /** + * Lorenz constructor + */ + constructor() { + super(); + + this.name = "Lorenz"; + this.module = "Default"; + this.description = "Enciphers characters using the World War 2 German Lorenz SZ cipher attachment."; + this.infoURL = "https://wikipedia.org/wiki/Lorenz_cipher"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Model", + type: "option", + "value": ["SZ40", "SZ42a", "SZ42b"] + }, + { + name: "Wheel Pattern", + type: "option", + "value": ["KH Pattern", "ZMUG Pattern", "BREAM Pattern", "No Pattern"] + }, + { + name: "KT-Schalter", + type: "boolean" + }, + { + name: "Mode", + type: "argSelector", + "value": [ + { + name: "Send", + on: [4], + off: [5] + }, + { + name: "Receive", + off: [4], + on: [5] + } + ] + }, + { + name: "Input Type", + type: "option", + "value": ["Plaintext", "ITA2"] + }, + { + name: "Output Type", + type: "option", + "value": ["Plaintext", "ITA2"] + }, + { + name: "Output Format", + type: "option", + "value": ["5/8/9", "+/-/."] + }, + { + name: "Ψ1 start (1-43)", + type: "number", + "value": 1 + }, + { + name: "Ψ2 start (1-47)", + type: "number", + "value": 1 + }, + { + name: "Ψ3 start (1-51)", + type: "number", + "value": 1 + }, + { + name: "Ψ4 start (1-53)", + type: "number", + "value": 1 + }, + { + name: "Ψ5 start (1-59)", + type: "number", + "value": 1 + }, + { + name: "Μ37 start (1-37)", + type: "number", + "value": 1 + }, + { + name: "Μ61 start (1-61)", + type: "number", + "value": 1 + }, + { + name: "Χ1 start (1-41)", + type: "number", + "value": 1 + }, + { + name: "Χ2 start (1-31)", + type: "number", + "value": 1 + }, + { + name: "Χ3 start (1-29)", + type: "number", + "value": 1 + }, + { + name: "Χ4 start (1-26)", + type: "number", + "value": 1 + }, + { + name: "Χ5 start (1-23)", + type: "number", + "value": 1 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + + const model = args[0], + pattern = args[1], + kt = args[2], + mode = args[3], + format = args[6]; + + var intype = args[4], + outtype = args[5], + s1 = args[7], + s2 = args[8], + s3 = args[9], + s4 = args[10], + s5 = args[11], + m37 = args[12], + m61 = args[13], + x1 = args[14], + x2 = args[15], + x3 = args[16], + x4 = args[17], + x5 = args[18], + figShifted = false; + + this.reverseTable(); + + if (s1<1 || s1>43) throw new OperationError("Ψ1 start must be between 1 and 43"); + if (s2<1 || s2>47) throw new OperationError("Ψ2 start must be between 1 and 47"); + if (s3<1 || s3>51) throw new OperationError("Ψ3 start must be between 1 and 51"); + if (s4<1 || s4>53) throw new OperationError("Ψ4 start must be between 1 and 53"); + if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59"); + if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37"); + if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61"); + if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41"); + if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31"); + if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29"); + if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26"); + if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23"); + + // Initialise chosen wheel pattern + var chosenSetting = INIT_PATTERNS[pattern]; + var chiSettings = chosenSetting["X"]; // Pin settings for Chi links (X) + var psiSettings = chosenSetting["S"]; // Pin settings for Psi links (S) + var muSettings = chosenSetting["M"]; // Pin settings for Motor links (M) + + var ita2 = ""; + if(mode == "Send") { + + // Convert input text to ITA2 (including figure/letter shifts) + ita2 = Array.prototype.map.call(input, function(character) { + var letter = character.toUpperCase(); + + if(intype == "Plaintext") { + if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character"); + + if( !figShifted && figShiftedChars.indexOf(letter) !== -1 ) { + // in letters mode and next char needs to be figure shifted + figShifted = true; + return "55" + figShiftArr[letter]; + } else if( figShifted ) { + // in figures mode and next char needs to be letter shifted + if(letter=="\n") return "34"; + if(letter=="\r") return "4"; + if( figShiftedChars.indexOf(letter) === -1 ) { + figShifted = false; + return "88" + letter; + } else { + return figShiftArr[letter]; + } + + } else { + if(letter=="\n") return "34"; + if(letter=="\r") return "4"; + return letter; + } + + } else { + + if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); + + return letter; + + } + + }); + + } else { + + // Receive input should always be ITA2 + ita2 = Array.prototype.map.call(input, function(character) { + var letter = character.toUpperCase(); + if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); + return letter; + }); + + } + + const ita2Input = ita2.join(""); + console.log(ita2Input); + + var thisPsi = []; + var thisChi = []; + var thisMu = []; + var m61lug = 0; + var m37lug = 0; + var p5 = [0,0,0]; + + const self = this; + const letters = Array.prototype.map.call(ita2Input, function(character) { + const letter = character.toUpperCase(); + + console.log(s1+' '+s2+' '+s3+' '+s4+' '+s5+' : '+m37+' '+m61+' : '+x1+' '+x2+' '+x3+' '+x4+' '+x5); + + var x2bptr = x2+1; + if(x2bptr==32) x2bptr=1; + var s1bptr = s1+1; + if(s1bptr==44) s1bptr=1; + + console.log('x2b1='+x2bptr+' s1b1='+s1bptr); + + thisChi = [ + chiSettings[1][x1-1], + chiSettings[2][x2-1], + chiSettings[3][x3-1], + chiSettings[4][x4-1], + chiSettings[5][x5-1] + ]; + + thisPsi = [ + psiSettings[1][s1-1], + psiSettings[2][s2-1], + psiSettings[3][s3-1], + psiSettings[4][s4-1], + psiSettings[5][s5-1] + ]; + + thisMu = [ + muSettings[1][m61-1], + muSettings[2][m37-1] + ]; + + console.log(letter + ' + ' + self.REVERSE_ITA2_TABLE[thisPsi.join("")] + ' + ' + self.REVERSE_ITA2_TABLE[thisChi.join("")]); + + if (typeof ITA2_TABLE[letter] == "undefined") { + return ""; + } + + var xorSum = []; + for(var i=0;i<=4;i++) { + xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i]; + } + const resultStr = xorSum.join(""); + + // Move Chi wheels one back after each letter + if(--x1 < 1) x1 = 41; + if(--x2 < 1) x2 = 31; + if(--x3 < 1) x3 = 29; + if(--x4 < 1) x4 = 26; + if(--x5 < 1) x5 = 23; + + // Motor wheel (61 pin) also moves one each letter + if(--m61 < 1) m61 = 61; + + // If M61 is set, we also move M37 + if(m61lug == 1) { + if(--m37 < 1) m37 = 37; + } + + var basicmotor = m37lug; + var totalmotor = basicmotor; + var lim = 0; + + // Limitations here + if(model=='SZ42a') { + // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position + lim = chiSettings[2][x2bptr-1]; + if(kt) { + if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 + } + console.log('BM='+basicmotor+', LM='+lim); + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if(basicmotor==0 && lim==1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if(model=='SZ42b') { + // Chi 2 one back + Psi 1 one back. + const x2b1lug = chiSettings[2][x2bptr-1]; + const s1b1lug = psiSettings[1][s1bptr-1]; + lim = 1; + if(x2b1lug==s1b1lug) lim=0; + if(kt) { + if(lim==p5[2]) { lim=0; } else { lim=1; } //p5 back 2 + } + console.log('BM='+basicmotor+', LM='+lim); + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if(basicmotor==0 && lim==1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if(model=="SZ40") { + // SZ40 + totalmotor = basicmotor; + console.log('TM='+basicmotor); + } else { + throw new OperationError("Lorenz model type not recognised"); + } + + // increment Psi wheels when current M37 lug active + if(totalmotor == 1) { + if(--s1 < 1) s1 = 43; + if(--s2 < 1) s2 = 47; + if(--s3 < 1) s3 = 51; + if(--s4 < 1) s4 = 53; + if(--s5 < 1) s5 = 59; + } + + m61lug = muSettings[1][m61-1]; + m37lug = muSettings[2][m37-1]; + + p5[2] = p5[1]; + p5[1] = p5[0]; + p5[0] = ITA2_TABLE[letter][4]; + console.log('p5='+ITA2_TABLE[letter]+' ('+letter+') = '+p5[0]); + + var rtnstr = self.REVERSE_ITA2_TABLE[resultStr]; + if(format=="5/8/9") { + if(rtnstr=="+") rtnstr="5"; + if(rtnstr=="-") rtnstr="8"; + if(rtnstr==".") rtnstr="9"; + } + return rtnstr; + }); + + var ita2output = letters.join(""); + var output = ""; + + if(mode == "Receive") { + + figShifted = false; + + // Convert output ITA2 to plaintext (including figure/letter shifts) + const out = Array.prototype.map.call(ita2output, function(letter) { + + if(outtype == "Plaintext") { + + if( letter == "5" || letter == "+" ) { + figShifted = true; + return; + } else if( letter == "8" || letter == "-" ) { + figShifted = false; + return; + } else if( letter == "9" ) { + return " "; + } else if( letter == "3" ) { + return "\n"; + } else if( letter == "4" ) { + return ""; + } + + + if(figShifted) { + return self.REVERSE_FIGSHIFT_TABLE[letter]; + } else { + return letter; + } + + } else { + return letter; + } + + }); + output = out.join(""); + + } else { + output = ita2output; + } + + return output; + + } + + /** + * Reverses the ITA2 Code lookup table + */ + reverseTable() { + this.REVERSE_ITA2_TABLE = {}; + this.REVERSE_FIGSHIFT_TABLE = {}; + + for (const letter in ITA2_TABLE) { + const code = ITA2_TABLE[letter]; + this.REVERSE_ITA2_TABLE[code] = letter; + } + for (const letter in figShiftArr) { + const ltr = figShiftArr[letter]; + this.REVERSE_FIGSHIFT_TABLE[ltr] = letter; + } + } + +} + +const ITA2_TABLE = { + "A": "11000", + "B": "10011", + "C": "01110", + "D": "10010", + "E": "10000", + "F": "10110", + "G": "01011", + "H": "00101", + "I": "01100", + "J": "11010", + "K": "11110", + "L": "01001", + "M": "00111", + "N": "00110", + "O": "00011", + "P": "01101", + "Q": "11101", + "R": "01010", + "S": "10100", + "T": "00001", + "U": "11100", + "V": "01111", + "W": "11001", + "X": "10111", + "Y": "10101", + "Z": "10001", + "3": "00010", + "4": "01000", + "9": "00100", + "/": "00000", + " ": "00100", + ".": "00100", + "8": "11111", + "5": "11011", + "-": "11111", + "+": "11011" +}; + +const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-'()/:=?,. \n\r"; +const validITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./"; +const figShiftedChars = "1234567890+-'()/:=?,." + +const figShiftArr = { + "1" : "Q", + "2" : "W", + "3" : "E", + "4" : "R", + "5" : "T", + "6" : "Y", + "7" : "U", + "8" : "I", + "9" : "O", + "0" : "P", + " " : "9", + "-" : "A", + "?" : "B", + ":" : "C", + "#" : "D", + "%" : "F", + "@" : "G", + "£" : "H", + "(" : "K", + ")" : "L", + "." : "M", + "," : "N", + "'" : "S", + "=" : "V", + "/" : "X", + "+" : "Z", + "\n" : "3", + "\r" : "4" +}; + +const INIT_PATTERNS = { + "No Pattern" : { + "X" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "S" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "M" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + } + + }, + "KH Pattern" : { + "X" : { + 1 : [0,1,0,0,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0], + 2 : [1,0,0,1,1,1,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,0,1,1,0,0], + 3 : [0,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,0], + 4 : [1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,1,0,0], + 5 : [1,1,0,0,1,1,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,0,0] + }, + "S" : { + 1 : [0,1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,1], + 2 : [0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1], + 3 : [0,1,0,1,0,1,0,0,1,1,1,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1], + 4 : [0,1,1,0,0,0,1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0], + 5 : [1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,0,1,0] + }, + "M": { + 1 : [0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,0], + 2 : [1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0] + } + }, + "ZMUG Pattern" : { + "X" : { + 1 : [0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,0], + 2 : [1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,1,1,0,0,0], + 3 : [0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,0,1,1,1,1,0], + 4 : [1,0,1,0,1,0,0,1,1,0,0,0,1,1,0,0,1,0,1,1,1,0,0,1,0,1], + 5 : [0,1,0,0,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,0,1], + }, + "S" : { + 1 : [1,1,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0], + 2 : [0,0,0,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1], + 3 : [0,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1], + 4 : [0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,1], + 5 : [1,0,0,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,0] + }, + "M" : { + 1 : [1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1], + 2 : [0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1] + } + }, + "BREAM Pattern" : { + "X" : { + 1 : [0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0], + 2 : [0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,1,1], + 3 : [1,1,0,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,0,1,1,1,0,0], + 4 : [1,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0], + 5 : [0,1,1,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0] + }, + "S" : { + 1 : [0,0,0,1,1,1,0,0,1,1,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0], + 2 : [1,1,0,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,0], + 3 : [1,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], + 4 : [0,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1], + 5 : [1,0,1,0,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0] + }, + "M" : { + 1 : [1,0,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,1,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1,1], + 2 : [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1] + } + } +}; + +export default Lorenz; From a7f61397f777e0c0e7d6da8645b7d2ceb5966e93 Mon Sep 17 00:00:00 2001 From: VirtualColossus <48803849+VirtualColossus@users.noreply.github.com> Date: Mon, 25 Mar 2019 13:26:26 +0000 Subject: [PATCH 02/17] Added Lorenz SZ40/42 Operation --- src/core/config/Categories.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 2fe8e8f72..72f2a43b3 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -106,7 +106,8 @@ "Enigma", "Bombe", "Multiple Bombe", - "Typex" + "Typex", + "Lorenz Encode" ] }, { From 93c41f044cf2cdfa799e329db5724ddfdcab36f5 Mon Sep 17 00:00:00 2001 From: Martin Gillow Date: Mon, 25 Mar 2019 13:31:13 +0000 Subject: [PATCH 03/17] Added Lorenz SZ40/42 operation --- src/core/operations/Lorenz.mjs | 606 +++++++++++++++++++++++++++++++++ 1 file changed, 606 insertions(+) create mode 100644 src/core/operations/Lorenz.mjs diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs new file mode 100644 index 000000000..72331727d --- /dev/null +++ b/src/core/operations/Lorenz.mjs @@ -0,0 +1,606 @@ +/** + * Emulation of the Lorenz SZ40/42a/42b cipher attachment. + * + * @author VirtualColossus [martin@virtualcolossus.co.uk] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Lorenz operation + */ +class Lorenz extends Operation { + + /** + * Lorenz constructor + */ + constructor() { + super(); + + this.name = "Lorenz"; + this.module = "Default"; + this.description = "Enciphers characters using the World War 2 German Lorenz SZ cipher attachment."; + this.infoURL = "https://wikipedia.org/wiki/Lorenz_cipher"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Model", + type: "option", + "value": ["SZ40", "SZ42a", "SZ42b"] + }, + { + name: "Wheel Pattern", + type: "option", + "value": ["KH Pattern", "ZMUG Pattern", "BREAM Pattern", "No Pattern"] + }, + { + name: "KT-Schalter", + type: "boolean" + }, + { + name: "Mode", + type: "argSelector", + "value": [ + { + name: "Send", + on: [4], + off: [5] + }, + { + name: "Receive", + off: [4], + on: [5] + } + ] + }, + { + name: "Input Type", + type: "option", + "value": ["Plaintext", "ITA2"] + }, + { + name: "Output Type", + type: "option", + "value": ["Plaintext", "ITA2"] + }, + { + name: "Output Format", + type: "option", + "value": ["5/8/9", "+/-/."] + }, + { + name: "Ψ1 start (1-43)", + type: "number", + "value": 1 + }, + { + name: "Ψ2 start (1-47)", + type: "number", + "value": 1 + }, + { + name: "Ψ3 start (1-51)", + type: "number", + "value": 1 + }, + { + name: "Ψ4 start (1-53)", + type: "number", + "value": 1 + }, + { + name: "Ψ5 start (1-59)", + type: "number", + "value": 1 + }, + { + name: "Μ37 start (1-37)", + type: "number", + "value": 1 + }, + { + name: "Μ61 start (1-61)", + type: "number", + "value": 1 + }, + { + name: "Χ1 start (1-41)", + type: "number", + "value": 1 + }, + { + name: "Χ2 start (1-31)", + type: "number", + "value": 1 + }, + { + name: "Χ3 start (1-29)", + type: "number", + "value": 1 + }, + { + name: "Χ4 start (1-26)", + type: "number", + "value": 1 + }, + { + name: "Χ5 start (1-23)", + type: "number", + "value": 1 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + + const model = args[0], + pattern = args[1], + kt = args[2], + mode = args[3], + format = args[6]; + + var intype = args[4], + outtype = args[5], + s1 = args[7], + s2 = args[8], + s3 = args[9], + s4 = args[10], + s5 = args[11], + m37 = args[12], + m61 = args[13], + x1 = args[14], + x2 = args[15], + x3 = args[16], + x4 = args[17], + x5 = args[18], + figShifted = false; + + this.reverseTable(); + + if (s1<1 || s1>43) throw new OperationError("Ψ1 start must be between 1 and 43"); + if (s2<1 || s2>47) throw new OperationError("Ψ2 start must be between 1 and 47"); + if (s3<1 || s3>51) throw new OperationError("Ψ3 start must be between 1 and 51"); + if (s4<1 || s4>53) throw new OperationError("Ψ4 start must be between 1 and 53"); + if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59"); + if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37"); + if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61"); + if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41"); + if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31"); + if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29"); + if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26"); + if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23"); + + // Initialise chosen wheel pattern + var chosenSetting = INIT_PATTERNS[pattern]; + var chiSettings = chosenSetting["X"]; // Pin settings for Chi links (X) + var psiSettings = chosenSetting["S"]; // Pin settings for Psi links (S) + var muSettings = chosenSetting["M"]; // Pin settings for Motor links (M) + + var ita2 = ""; + if(mode == "Send") { + + // Convert input text to ITA2 (including figure/letter shifts) + ita2 = Array.prototype.map.call(input, function(character) { + var letter = character.toUpperCase(); + + if(intype == "Plaintext") { + if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character"); + + if( !figShifted && figShiftedChars.indexOf(letter) !== -1 ) { + // in letters mode and next char needs to be figure shifted + figShifted = true; + return "55" + figShiftArr[letter]; + } else if( figShifted ) { + // in figures mode and next char needs to be letter shifted + if(letter=="\n") return "34"; + if(letter=="\r") return "4"; + if( figShiftedChars.indexOf(letter) === -1 ) { + figShifted = false; + return "88" + letter; + } else { + return figShiftArr[letter]; + } + + } else { + if(letter=="\n") return "34"; + if(letter=="\r") return "4"; + return letter; + } + + } else { + + if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); + + return letter; + + } + + }); + + } else { + + // Receive input should always be ITA2 + ita2 = Array.prototype.map.call(input, function(character) { + var letter = character.toUpperCase(); + if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); + return letter; + }); + + } + + const ita2Input = ita2.join(""); + console.log(ita2Input); + + var thisPsi = []; + var thisChi = []; + var thisMu = []; + var m61lug = 0; + var m37lug = 0; + var p5 = [0,0,0]; + + const self = this; + const letters = Array.prototype.map.call(ita2Input, function(character) { + const letter = character.toUpperCase(); + + console.log(s1+' '+s2+' '+s3+' '+s4+' '+s5+' : '+m37+' '+m61+' : '+x1+' '+x2+' '+x3+' '+x4+' '+x5); + + var x2bptr = x2+1; + if(x2bptr==32) x2bptr=1; + var s1bptr = s1+1; + if(s1bptr==44) s1bptr=1; + + console.log('x2b1='+x2bptr+' s1b1='+s1bptr); + + thisChi = [ + chiSettings[1][x1-1], + chiSettings[2][x2-1], + chiSettings[3][x3-1], + chiSettings[4][x4-1], + chiSettings[5][x5-1] + ]; + + thisPsi = [ + psiSettings[1][s1-1], + psiSettings[2][s2-1], + psiSettings[3][s3-1], + psiSettings[4][s4-1], + psiSettings[5][s5-1] + ]; + + thisMu = [ + muSettings[1][m61-1], + muSettings[2][m37-1] + ]; + + console.log(letter + ' + ' + self.REVERSE_ITA2_TABLE[thisPsi.join("")] + ' + ' + self.REVERSE_ITA2_TABLE[thisChi.join("")]); + + if (typeof ITA2_TABLE[letter] == "undefined") { + return ""; + } + + var xorSum = []; + for(var i=0;i<=4;i++) { + xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i]; + } + const resultStr = xorSum.join(""); + + // Move Chi wheels one back after each letter + if(--x1 < 1) x1 = 41; + if(--x2 < 1) x2 = 31; + if(--x3 < 1) x3 = 29; + if(--x4 < 1) x4 = 26; + if(--x5 < 1) x5 = 23; + + // Motor wheel (61 pin) also moves one each letter + if(--m61 < 1) m61 = 61; + + // If M61 is set, we also move M37 + if(m61lug == 1) { + if(--m37 < 1) m37 = 37; + } + + var basicmotor = m37lug; + var totalmotor = basicmotor; + var lim = 0; + + // Limitations here + if(model=='SZ42a') { + // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position + lim = chiSettings[2][x2bptr-1]; + if(kt) { + if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 + } + console.log('BM='+basicmotor+', LM='+lim); + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if(basicmotor==0 && lim==1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if(model=='SZ42b') { + // Chi 2 one back + Psi 1 one back. + const x2b1lug = chiSettings[2][x2bptr-1]; + const s1b1lug = psiSettings[1][s1bptr-1]; + lim = 1; + if(x2b1lug==s1b1lug) lim=0; + if(kt) { + if(lim==p5[2]) { lim=0; } else { lim=1; } //p5 back 2 + } + console.log('BM='+basicmotor+', LM='+lim); + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if(basicmotor==0 && lim==1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if(model=="SZ40") { + // SZ40 + totalmotor = basicmotor; + console.log('TM='+basicmotor); + } else { + throw new OperationError("Lorenz model type not recognised"); + } + + // increment Psi wheels when current M37 lug active + if(totalmotor == 1) { + if(--s1 < 1) s1 = 43; + if(--s2 < 1) s2 = 47; + if(--s3 < 1) s3 = 51; + if(--s4 < 1) s4 = 53; + if(--s5 < 1) s5 = 59; + } + + m61lug = muSettings[1][m61-1]; + m37lug = muSettings[2][m37-1]; + + p5[2] = p5[1]; + p5[1] = p5[0]; + p5[0] = ITA2_TABLE[letter][4]; + console.log('p5='+ITA2_TABLE[letter]+' ('+letter+') = '+p5[0]); + + var rtnstr = self.REVERSE_ITA2_TABLE[resultStr]; + if(format=="5/8/9") { + if(rtnstr=="+") rtnstr="5"; + if(rtnstr=="-") rtnstr="8"; + if(rtnstr==".") rtnstr="9"; + } + return rtnstr; + }); + + var ita2output = letters.join(""); + var output = ""; + + if(mode == "Receive") { + + figShifted = false; + + // Convert output ITA2 to plaintext (including figure/letter shifts) + const out = Array.prototype.map.call(ita2output, function(letter) { + + if(outtype == "Plaintext") { + + if( letter == "5" || letter == "+" ) { + figShifted = true; + return; + } else if( letter == "8" || letter == "-" ) { + figShifted = false; + return; + } else if( letter == "9" ) { + return " "; + } else if( letter == "3" ) { + return "\n"; + } else if( letter == "4" ) { + return ""; + } + + + if(figShifted) { + return self.REVERSE_FIGSHIFT_TABLE[letter]; + } else { + return letter; + } + + } else { + return letter; + } + + }); + output = out.join(""); + + } else { + output = ita2output; + } + + return output; + + } + + /** + * Reverses the ITA2 Code lookup table + */ + reverseTable() { + this.REVERSE_ITA2_TABLE = {}; + this.REVERSE_FIGSHIFT_TABLE = {}; + + for (const letter in ITA2_TABLE) { + const code = ITA2_TABLE[letter]; + this.REVERSE_ITA2_TABLE[code] = letter; + } + for (const letter in figShiftArr) { + const ltr = figShiftArr[letter]; + this.REVERSE_FIGSHIFT_TABLE[ltr] = letter; + } + } + +} + +const ITA2_TABLE = { + "A": "11000", + "B": "10011", + "C": "01110", + "D": "10010", + "E": "10000", + "F": "10110", + "G": "01011", + "H": "00101", + "I": "01100", + "J": "11010", + "K": "11110", + "L": "01001", + "M": "00111", + "N": "00110", + "O": "00011", + "P": "01101", + "Q": "11101", + "R": "01010", + "S": "10100", + "T": "00001", + "U": "11100", + "V": "01111", + "W": "11001", + "X": "10111", + "Y": "10101", + "Z": "10001", + "3": "00010", + "4": "01000", + "9": "00100", + "/": "00000", + " ": "00100", + ".": "00100", + "8": "11111", + "5": "11011", + "-": "11111", + "+": "11011" +}; + +const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-'()/:=?,. \n\r"; +const validITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./"; +const figShiftedChars = "1234567890+-'()/:=?,." + +const figShiftArr = { + "1" : "Q", + "2" : "W", + "3" : "E", + "4" : "R", + "5" : "T", + "6" : "Y", + "7" : "U", + "8" : "I", + "9" : "O", + "0" : "P", + " " : "9", + "-" : "A", + "?" : "B", + ":" : "C", + "#" : "D", + "%" : "F", + "@" : "G", + "£" : "H", + "(" : "K", + ")" : "L", + "." : "M", + "," : "N", + "'" : "S", + "=" : "V", + "/" : "X", + "+" : "Z", + "\n" : "3", + "\r" : "4" +}; + +const INIT_PATTERNS = { + "No Pattern" : { + "X" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "S" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "M" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + } + + }, + "KH Pattern" : { + "X" : { + 1 : [0,1,0,0,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0], + 2 : [1,0,0,1,1,1,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,0,1,1,0,0], + 3 : [0,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,0], + 4 : [1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,1,0,0], + 5 : [1,1,0,0,1,1,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,0,0] + }, + "S" : { + 1 : [0,1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,1], + 2 : [0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1], + 3 : [0,1,0,1,0,1,0,0,1,1,1,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1], + 4 : [0,1,1,0,0,0,1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0], + 5 : [1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,0,1,0] + }, + "M": { + 1 : [0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,0], + 2 : [1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0] + } + }, + "ZMUG Pattern" : { + "X" : { + 1 : [0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,0], + 2 : [1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,1,1,0,0,0], + 3 : [0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,0,1,1,1,1,0], + 4 : [1,0,1,0,1,0,0,1,1,0,0,0,1,1,0,0,1,0,1,1,1,0,0,1,0,1], + 5 : [0,1,0,0,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,0,1], + }, + "S" : { + 1 : [1,1,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0], + 2 : [0,0,0,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1], + 3 : [0,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1], + 4 : [0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,1], + 5 : [1,0,0,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,0] + }, + "M" : { + 1 : [1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1], + 2 : [0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1] + } + }, + "BREAM Pattern" : { + "X" : { + 1 : [0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0], + 2 : [0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,1,1], + 3 : [1,1,0,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,0,1,1,1,0,0], + 4 : [1,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0], + 5 : [0,1,1,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0] + }, + "S" : { + 1 : [0,0,0,1,1,1,0,0,1,1,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0], + 2 : [1,1,0,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,0], + 3 : [1,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], + 4 : [0,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1], + 5 : [1,0,1,0,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0] + }, + "M" : { + 1 : [1,0,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,1,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1,1], + 2 : [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1] + } + } +}; + +export default Lorenz; From b6eb851a1312c78f285c00bc9b67dba1347bd9f1 Mon Sep 17 00:00:00 2001 From: Martin Gillow Date: Mon, 25 Mar 2019 13:34:25 +0000 Subject: [PATCH 04/17] Added Lorenz SZ40/42 operation --- src/core/config/Categories.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 2fe8e8f72..83a8fb16f 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -106,7 +106,8 @@ "Enigma", "Bombe", "Multiple Bombe", - "Typex" + "Typex", + "Lorenz" ] }, { From 578502187df673a922c5955b4ad8e0139d3dca0d Mon Sep 17 00:00:00 2001 From: martin gillow Date: Mon, 25 Mar 2019 19:37:20 +0000 Subject: [PATCH 05/17] Added custom lug option --- src/core/operations/Lorenz.mjs | 606 +++++++++++++++++++++++++++++++++ 1 file changed, 606 insertions(+) create mode 100644 src/core/operations/Lorenz.mjs diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs new file mode 100644 index 000000000..72331727d --- /dev/null +++ b/src/core/operations/Lorenz.mjs @@ -0,0 +1,606 @@ +/** + * Emulation of the Lorenz SZ40/42a/42b cipher attachment. + * + * @author VirtualColossus [martin@virtualcolossus.co.uk] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Lorenz operation + */ +class Lorenz extends Operation { + + /** + * Lorenz constructor + */ + constructor() { + super(); + + this.name = "Lorenz"; + this.module = "Default"; + this.description = "Enciphers characters using the World War 2 German Lorenz SZ cipher attachment."; + this.infoURL = "https://wikipedia.org/wiki/Lorenz_cipher"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Model", + type: "option", + "value": ["SZ40", "SZ42a", "SZ42b"] + }, + { + name: "Wheel Pattern", + type: "option", + "value": ["KH Pattern", "ZMUG Pattern", "BREAM Pattern", "No Pattern"] + }, + { + name: "KT-Schalter", + type: "boolean" + }, + { + name: "Mode", + type: "argSelector", + "value": [ + { + name: "Send", + on: [4], + off: [5] + }, + { + name: "Receive", + off: [4], + on: [5] + } + ] + }, + { + name: "Input Type", + type: "option", + "value": ["Plaintext", "ITA2"] + }, + { + name: "Output Type", + type: "option", + "value": ["Plaintext", "ITA2"] + }, + { + name: "Output Format", + type: "option", + "value": ["5/8/9", "+/-/."] + }, + { + name: "Ψ1 start (1-43)", + type: "number", + "value": 1 + }, + { + name: "Ψ2 start (1-47)", + type: "number", + "value": 1 + }, + { + name: "Ψ3 start (1-51)", + type: "number", + "value": 1 + }, + { + name: "Ψ4 start (1-53)", + type: "number", + "value": 1 + }, + { + name: "Ψ5 start (1-59)", + type: "number", + "value": 1 + }, + { + name: "Μ37 start (1-37)", + type: "number", + "value": 1 + }, + { + name: "Μ61 start (1-61)", + type: "number", + "value": 1 + }, + { + name: "Χ1 start (1-41)", + type: "number", + "value": 1 + }, + { + name: "Χ2 start (1-31)", + type: "number", + "value": 1 + }, + { + name: "Χ3 start (1-29)", + type: "number", + "value": 1 + }, + { + name: "Χ4 start (1-26)", + type: "number", + "value": 1 + }, + { + name: "Χ5 start (1-23)", + type: "number", + "value": 1 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + + const model = args[0], + pattern = args[1], + kt = args[2], + mode = args[3], + format = args[6]; + + var intype = args[4], + outtype = args[5], + s1 = args[7], + s2 = args[8], + s3 = args[9], + s4 = args[10], + s5 = args[11], + m37 = args[12], + m61 = args[13], + x1 = args[14], + x2 = args[15], + x3 = args[16], + x4 = args[17], + x5 = args[18], + figShifted = false; + + this.reverseTable(); + + if (s1<1 || s1>43) throw new OperationError("Ψ1 start must be between 1 and 43"); + if (s2<1 || s2>47) throw new OperationError("Ψ2 start must be between 1 and 47"); + if (s3<1 || s3>51) throw new OperationError("Ψ3 start must be between 1 and 51"); + if (s4<1 || s4>53) throw new OperationError("Ψ4 start must be between 1 and 53"); + if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59"); + if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37"); + if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61"); + if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41"); + if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31"); + if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29"); + if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26"); + if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23"); + + // Initialise chosen wheel pattern + var chosenSetting = INIT_PATTERNS[pattern]; + var chiSettings = chosenSetting["X"]; // Pin settings for Chi links (X) + var psiSettings = chosenSetting["S"]; // Pin settings for Psi links (S) + var muSettings = chosenSetting["M"]; // Pin settings for Motor links (M) + + var ita2 = ""; + if(mode == "Send") { + + // Convert input text to ITA2 (including figure/letter shifts) + ita2 = Array.prototype.map.call(input, function(character) { + var letter = character.toUpperCase(); + + if(intype == "Plaintext") { + if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character"); + + if( !figShifted && figShiftedChars.indexOf(letter) !== -1 ) { + // in letters mode and next char needs to be figure shifted + figShifted = true; + return "55" + figShiftArr[letter]; + } else if( figShifted ) { + // in figures mode and next char needs to be letter shifted + if(letter=="\n") return "34"; + if(letter=="\r") return "4"; + if( figShiftedChars.indexOf(letter) === -1 ) { + figShifted = false; + return "88" + letter; + } else { + return figShiftArr[letter]; + } + + } else { + if(letter=="\n") return "34"; + if(letter=="\r") return "4"; + return letter; + } + + } else { + + if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); + + return letter; + + } + + }); + + } else { + + // Receive input should always be ITA2 + ita2 = Array.prototype.map.call(input, function(character) { + var letter = character.toUpperCase(); + if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); + return letter; + }); + + } + + const ita2Input = ita2.join(""); + console.log(ita2Input); + + var thisPsi = []; + var thisChi = []; + var thisMu = []; + var m61lug = 0; + var m37lug = 0; + var p5 = [0,0,0]; + + const self = this; + const letters = Array.prototype.map.call(ita2Input, function(character) { + const letter = character.toUpperCase(); + + console.log(s1+' '+s2+' '+s3+' '+s4+' '+s5+' : '+m37+' '+m61+' : '+x1+' '+x2+' '+x3+' '+x4+' '+x5); + + var x2bptr = x2+1; + if(x2bptr==32) x2bptr=1; + var s1bptr = s1+1; + if(s1bptr==44) s1bptr=1; + + console.log('x2b1='+x2bptr+' s1b1='+s1bptr); + + thisChi = [ + chiSettings[1][x1-1], + chiSettings[2][x2-1], + chiSettings[3][x3-1], + chiSettings[4][x4-1], + chiSettings[5][x5-1] + ]; + + thisPsi = [ + psiSettings[1][s1-1], + psiSettings[2][s2-1], + psiSettings[3][s3-1], + psiSettings[4][s4-1], + psiSettings[5][s5-1] + ]; + + thisMu = [ + muSettings[1][m61-1], + muSettings[2][m37-1] + ]; + + console.log(letter + ' + ' + self.REVERSE_ITA2_TABLE[thisPsi.join("")] + ' + ' + self.REVERSE_ITA2_TABLE[thisChi.join("")]); + + if (typeof ITA2_TABLE[letter] == "undefined") { + return ""; + } + + var xorSum = []; + for(var i=0;i<=4;i++) { + xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i]; + } + const resultStr = xorSum.join(""); + + // Move Chi wheels one back after each letter + if(--x1 < 1) x1 = 41; + if(--x2 < 1) x2 = 31; + if(--x3 < 1) x3 = 29; + if(--x4 < 1) x4 = 26; + if(--x5 < 1) x5 = 23; + + // Motor wheel (61 pin) also moves one each letter + if(--m61 < 1) m61 = 61; + + // If M61 is set, we also move M37 + if(m61lug == 1) { + if(--m37 < 1) m37 = 37; + } + + var basicmotor = m37lug; + var totalmotor = basicmotor; + var lim = 0; + + // Limitations here + if(model=='SZ42a') { + // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position + lim = chiSettings[2][x2bptr-1]; + if(kt) { + if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 + } + console.log('BM='+basicmotor+', LM='+lim); + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if(basicmotor==0 && lim==1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if(model=='SZ42b') { + // Chi 2 one back + Psi 1 one back. + const x2b1lug = chiSettings[2][x2bptr-1]; + const s1b1lug = psiSettings[1][s1bptr-1]; + lim = 1; + if(x2b1lug==s1b1lug) lim=0; + if(kt) { + if(lim==p5[2]) { lim=0; } else { lim=1; } //p5 back 2 + } + console.log('BM='+basicmotor+', LM='+lim); + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if(basicmotor==0 && lim==1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if(model=="SZ40") { + // SZ40 + totalmotor = basicmotor; + console.log('TM='+basicmotor); + } else { + throw new OperationError("Lorenz model type not recognised"); + } + + // increment Psi wheels when current M37 lug active + if(totalmotor == 1) { + if(--s1 < 1) s1 = 43; + if(--s2 < 1) s2 = 47; + if(--s3 < 1) s3 = 51; + if(--s4 < 1) s4 = 53; + if(--s5 < 1) s5 = 59; + } + + m61lug = muSettings[1][m61-1]; + m37lug = muSettings[2][m37-1]; + + p5[2] = p5[1]; + p5[1] = p5[0]; + p5[0] = ITA2_TABLE[letter][4]; + console.log('p5='+ITA2_TABLE[letter]+' ('+letter+') = '+p5[0]); + + var rtnstr = self.REVERSE_ITA2_TABLE[resultStr]; + if(format=="5/8/9") { + if(rtnstr=="+") rtnstr="5"; + if(rtnstr=="-") rtnstr="8"; + if(rtnstr==".") rtnstr="9"; + } + return rtnstr; + }); + + var ita2output = letters.join(""); + var output = ""; + + if(mode == "Receive") { + + figShifted = false; + + // Convert output ITA2 to plaintext (including figure/letter shifts) + const out = Array.prototype.map.call(ita2output, function(letter) { + + if(outtype == "Plaintext") { + + if( letter == "5" || letter == "+" ) { + figShifted = true; + return; + } else if( letter == "8" || letter == "-" ) { + figShifted = false; + return; + } else if( letter == "9" ) { + return " "; + } else if( letter == "3" ) { + return "\n"; + } else if( letter == "4" ) { + return ""; + } + + + if(figShifted) { + return self.REVERSE_FIGSHIFT_TABLE[letter]; + } else { + return letter; + } + + } else { + return letter; + } + + }); + output = out.join(""); + + } else { + output = ita2output; + } + + return output; + + } + + /** + * Reverses the ITA2 Code lookup table + */ + reverseTable() { + this.REVERSE_ITA2_TABLE = {}; + this.REVERSE_FIGSHIFT_TABLE = {}; + + for (const letter in ITA2_TABLE) { + const code = ITA2_TABLE[letter]; + this.REVERSE_ITA2_TABLE[code] = letter; + } + for (const letter in figShiftArr) { + const ltr = figShiftArr[letter]; + this.REVERSE_FIGSHIFT_TABLE[ltr] = letter; + } + } + +} + +const ITA2_TABLE = { + "A": "11000", + "B": "10011", + "C": "01110", + "D": "10010", + "E": "10000", + "F": "10110", + "G": "01011", + "H": "00101", + "I": "01100", + "J": "11010", + "K": "11110", + "L": "01001", + "M": "00111", + "N": "00110", + "O": "00011", + "P": "01101", + "Q": "11101", + "R": "01010", + "S": "10100", + "T": "00001", + "U": "11100", + "V": "01111", + "W": "11001", + "X": "10111", + "Y": "10101", + "Z": "10001", + "3": "00010", + "4": "01000", + "9": "00100", + "/": "00000", + " ": "00100", + ".": "00100", + "8": "11111", + "5": "11011", + "-": "11111", + "+": "11011" +}; + +const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-'()/:=?,. \n\r"; +const validITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./"; +const figShiftedChars = "1234567890+-'()/:=?,." + +const figShiftArr = { + "1" : "Q", + "2" : "W", + "3" : "E", + "4" : "R", + "5" : "T", + "6" : "Y", + "7" : "U", + "8" : "I", + "9" : "O", + "0" : "P", + " " : "9", + "-" : "A", + "?" : "B", + ":" : "C", + "#" : "D", + "%" : "F", + "@" : "G", + "£" : "H", + "(" : "K", + ")" : "L", + "." : "M", + "," : "N", + "'" : "S", + "=" : "V", + "/" : "X", + "+" : "Z", + "\n" : "3", + "\r" : "4" +}; + +const INIT_PATTERNS = { + "No Pattern" : { + "X" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "S" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "M" : { + 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + } + + }, + "KH Pattern" : { + "X" : { + 1 : [0,1,0,0,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0], + 2 : [1,0,0,1,1,1,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,0,1,1,0,0], + 3 : [0,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,0], + 4 : [1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,1,0,0], + 5 : [1,1,0,0,1,1,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,0,0] + }, + "S" : { + 1 : [0,1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,1], + 2 : [0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1], + 3 : [0,1,0,1,0,1,0,0,1,1,1,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1], + 4 : [0,1,1,0,0,0,1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0], + 5 : [1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,0,1,0] + }, + "M": { + 1 : [0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,0], + 2 : [1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0] + } + }, + "ZMUG Pattern" : { + "X" : { + 1 : [0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,0], + 2 : [1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,1,1,0,0,0], + 3 : [0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,0,1,1,1,1,0], + 4 : [1,0,1,0,1,0,0,1,1,0,0,0,1,1,0,0,1,0,1,1,1,0,0,1,0,1], + 5 : [0,1,0,0,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,0,1], + }, + "S" : { + 1 : [1,1,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0], + 2 : [0,0,0,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1], + 3 : [0,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1], + 4 : [0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,1], + 5 : [1,0,0,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,0] + }, + "M" : { + 1 : [1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1], + 2 : [0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1] + } + }, + "BREAM Pattern" : { + "X" : { + 1 : [0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0], + 2 : [0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,1,1], + 3 : [1,1,0,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,0,1,1,1,0,0], + 4 : [1,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0], + 5 : [0,1,1,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0] + }, + "S" : { + 1 : [0,0,0,1,1,1,0,0,1,1,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0], + 2 : [1,1,0,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,0], + 3 : [1,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], + 4 : [0,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1], + 5 : [1,0,1,0,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0] + }, + "M" : { + 1 : [1,0,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,1,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1,1], + 2 : [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1] + } + } +}; + +export default Lorenz; From 444fb4555b870b9a5df34447f49d2bf259ca2de3 Mon Sep 17 00:00:00 2001 From: martin gillow Date: Mon, 25 Mar 2019 21:10:47 +0000 Subject: [PATCH 06/17] Custom wheel settings --- src/core/operations/Lorenz.mjs | 143 ++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 4 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 72331727d..6eda5058d 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -23,7 +23,7 @@ class Lorenz extends Operation { this.name = "Lorenz"; this.module = "Default"; this.description = "Enciphers characters using the World War 2 German Lorenz SZ cipher attachment."; - this.infoURL = "https://wikipedia.org/wiki/Lorenz_cipher"; + this.infoURL = "https://lorenz.virtualcolossus.co.uk"; this.inputType = "string"; this.outputType = "string"; this.args = [ @@ -34,8 +34,29 @@ class Lorenz extends Operation { }, { name: "Wheel Pattern", - type: "option", - "value": ["KH Pattern", "ZMUG Pattern", "BREAM Pattern", "No Pattern"] + type: "argSelector", + "value": [ + { + name: "KH Pattern", + off: [19,20,21,22,23,24,25,26,27,28,29,30], + }, + { + name: "ZMUG Pattern", + off: [19,20,21,22,23,24,25,26,27,28,29,30] + }, + { + name: "BREAM Pattern", + off: [19,20,21,22,23,24,25,26,27,28,29,30] + }, + { + name: "No Pattern", + off: [19,20,21,22,23,24,25,26,27,28,29,30] + }, + { + name: "Custom", + on: [19,20,21,22,23,24,25,26,27,28,29,30] + } + ] }, { name: "KT-Schalter", @@ -131,6 +152,66 @@ class Lorenz extends Operation { name: "Χ5 start (1-23)", type: "number", "value": 1 + }, + { + name: "Ψ1 lugs (43)", + type: "string", + value: ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x" + }, + { + name: "Ψ2 lugs (47)", + type: "string", + value: ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x" + }, + { + name: "Ψ3 lugs (51)", + type: "string", + value: ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x" + }, + { + name: "Ψ4 lugs (53)", + type: "string", + value: ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x." + }, + { + name: "Ψ5 lugs (59)", + type: "string", + value: "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x." + }, + { + name: "Μ37 lugs (37)", + type: "string", + value: "x.x.x.x.x.x...x.x.x...x.x.x...x.x...." + }, + { + name: "Μ61 lugs (61)", + type: "string", + value: ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx..." + }, + { + name: "Χ1 lugs (41)", + type: "string", + value: ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx.." + }, + { + name: "Χ2 lugs (31)", + type: "string", + value: "x..xxx...x.xxxx..xx..x..xx.xx.." + }, + { + name: "Χ3 lugs (29)", + type: "string", + value: "..xx..x.xxx...xx...xx..xx.xx." + }, + { + name: "Χ4 lugs (26)", + type: "string", + value: "xx..x..xxxx..xx.xxx....x.." + }, + { + name: "Χ5 lugs (23)", + type: "string", + value: "xx..xx....xxxx.x..x.x.." } ]; } @@ -162,6 +243,18 @@ class Lorenz extends Operation { x3 = args[16], x4 = args[17], x5 = args[18], + lugs1 = args[19], + lugs2 = args[20], + lugs3 = args[21], + lugs4 = args[22], + lugs5 = args[23], + lugm37 = args[24], + lugm61 = args[25], + lugx1 = args[26], + lugx2 = args[27], + lugx3 = args[28], + lugx4 = args[29], + lugx5 = args[30], figShifted = false; this.reverseTable(); @@ -180,7 +273,38 @@ class Lorenz extends Operation { if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23"); // Initialise chosen wheel pattern - var chosenSetting = INIT_PATTERNS[pattern]; + if(pattern=="Custom") { + var re = new RegExp("^[\.xX]*$"); + if (lugs1.length != 43 || !re.test(lugs1) ) throw new OperationError("Ψ1 custom lugs must be 43 long and can only include . or x "); + if (lugs2.length != 47 || !re.test(lugs2) ) throw new OperationError("Ψ2 custom lugs must be 47 long and can only include . or x"); + if (lugs3.length != 51 || !re.test(lugs3) ) throw new OperationError("Ψ3 custom lugs must be 51 long and can only include . or x"); + if (lugs4.length != 53 || !re.test(lugs4) ) throw new OperationError("Ψ4 custom lugs must be 53 long and can only include . or x"); + if (lugs5.length != 59 || !re.test(lugs5) ) throw new OperationError("Ψ5 custom lugs must be 59 long and can only include . or x"); + if (lugm37.length != 37 || !re.test(lugm37) ) throw new OperationError("M37 custom lugs must be 37 long and can only include . or x"); + if (lugm61.length != 61 || !re.test(lugm61) ) throw new OperationError("M61 custom lugs must be 61 long and can only include . or x"); + if (lugx1.length != 41 || !re.test(lugx1) ) throw new OperationError("Χ1 custom lugs must be 41 long and can only include . or x"); + if (lugx2.length != 31 || !re.test(lugx2) ) throw new OperationError("Χ2 custom lugs must be 31 long and can only include . or x"); + if (lugx3.length != 29 || !re.test(lugx3) ) throw new OperationError("Χ3 custom lugs must be 29 long and can only include . or x"); + if (lugx4.length != 26 || !re.test(lugx4) ) throw new OperationError("Χ4 custom lugs must be 26 long and can only include . or x"); + if (lugx5.length != 23 || !re.test(lugx5) ) throw new OperationError("Χ5 custom lugs must be 23 long and can only include . or x"); + var chosenSetting = INIT_PATTERNS["No Pattern"]; + console.log(chosenSetting); + chosenSetting["S"][1] = this.readLugs(lugs1); + chosenSetting["S"][2] = this.readLugs(lugs2); + chosenSetting["S"][3] = this.readLugs(lugs3); + chosenSetting["S"][4] = this.readLugs(lugs4); + chosenSetting["S"][5] = this.readLugs(lugs5); + chosenSetting["M"][1] = this.readLugs(lugm37); + chosenSetting["M"][2] = this.readLugs(lugm61); + chosenSetting["X"][1] = this.readLugs(lugx1); + chosenSetting["X"][2] = this.readLugs(lugx2); + chosenSetting["X"][3] = this.readLugs(lugx3); + chosenSetting["X"][4] = this.readLugs(lugx4); + chosenSetting["X"][5] = this.readLugs(lugx5); + console.log(chosenSetting); + } else { + var chosenSetting = INIT_PATTERNS[pattern]; + } var chiSettings = chosenSetting["X"]; // Pin settings for Chi links (X) var psiSettings = chosenSetting["S"]; // Pin settings for Psi links (S) var muSettings = chosenSetting["M"]; // Pin settings for Motor links (M) @@ -443,6 +567,17 @@ class Lorenz extends Operation { } } + readLugs(lugstr) { + var arr = Array.prototype.map.call(lugstr, function(lug) { + if(lug==".") { + return 0; + } else { + return 1; + } + }); + return arr; + } + } const ITA2_TABLE = { From 0397ba857f162c293ac98b2a2667733a625ecfad Mon Sep 17 00:00:00 2001 From: Martin Gillow Date: Wed, 27 Mar 2019 13:02:18 +0000 Subject: [PATCH 07/17] Fixed motor wheel movement --- src/core/operations/Lorenz.mjs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 6eda5058d..c1271f159 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -367,23 +367,21 @@ class Lorenz extends Operation { var thisPsi = []; var thisChi = []; var thisMu = []; - var m61lug = 0; - var m37lug = 0; + var m61lug = muSettings[1][m61-1]; + var m37lug = muSettings[2][m37-1]; var p5 = [0,0,0]; const self = this; const letters = Array.prototype.map.call(ita2Input, function(character) { const letter = character.toUpperCase(); - console.log(s1+' '+s2+' '+s3+' '+s4+' '+s5+' : '+m37+' '+m61+' : '+x1+' '+x2+' '+x3+' '+x4+' '+x5); + //console.log(s1+' '+s2+' '+s3+' '+s4+' '+s5+' : '+m37+' '+m61+' : '+x1+' '+x2+' '+x3+' '+x4+' '+x5); var x2bptr = x2+1; if(x2bptr==32) x2bptr=1; var s1bptr = s1+1; if(s1bptr==44) s1bptr=1; - console.log('x2b1='+x2bptr+' s1b1='+s1bptr); - thisChi = [ chiSettings[1][x1-1], chiSettings[2][x2-1], @@ -443,13 +441,14 @@ class Lorenz extends Operation { if(kt) { if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 } - console.log('BM='+basicmotor+', LM='+lim); + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] if(basicmotor==0 && lim==1) { totalmotor = 0; } else { totalmotor = 1; } + console.log('BM='+basicmotor+', LM='+lim+', TM='+totalmotor); } else if(model=='SZ42b') { // Chi 2 one back + Psi 1 one back. @@ -476,7 +475,7 @@ class Lorenz extends Operation { throw new OperationError("Lorenz model type not recognised"); } - // increment Psi wheels when current M37 lug active + // increment Psi wheels when current totalmotor active if(totalmotor == 1) { if(--s1 < 1) s1 = 43; if(--s2 < 1) s2 = 47; From 4f8fc8d65ed4b14accaa22e96ba931c1679d7ac9 Mon Sep 17 00:00:00 2001 From: martin gillow Date: Wed, 27 Mar 2019 20:44:57 +0000 Subject: [PATCH 08/17] Fixed p5 limitation --- src/core/operations/Lorenz.mjs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index c1271f159..057f9cb3c 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -368,7 +368,7 @@ class Lorenz extends Operation { var thisChi = []; var thisMu = []; var m61lug = muSettings[1][m61-1]; - var m37lug = muSettings[2][m37-1]; + var m37lug = 0; var p5 = [0,0,0]; const self = this; @@ -434,12 +434,18 @@ class Lorenz extends Operation { var totalmotor = basicmotor; var lim = 0; + p5[2] = p5[1]; + p5[1] = p5[0]; + p5[0] = ITA2_TABLE[letter][4]; + console.log('p5='+ITA2_TABLE[letter]+' ('+letter+') = '+p5[0]); + // Limitations here if(model=='SZ42a') { // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position lim = chiSettings[2][x2bptr-1]; if(kt) { - if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 + console.log('lim='+lim+', p5-2='+p5[2]); + if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 } // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] @@ -487,11 +493,6 @@ class Lorenz extends Operation { m61lug = muSettings[1][m61-1]; m37lug = muSettings[2][m37-1]; - p5[2] = p5[1]; - p5[1] = p5[0]; - p5[0] = ITA2_TABLE[letter][4]; - console.log('p5='+ITA2_TABLE[letter]+' ('+letter+') = '+p5[0]); - var rtnstr = self.REVERSE_ITA2_TABLE[resultStr]; if(format=="5/8/9") { if(rtnstr=="+") rtnstr="5"; From 39f338370955d89e35bb3316b3debffea004e04f Mon Sep 17 00:00:00 2001 From: martin gillow Date: Wed, 27 Mar 2019 20:57:04 +0000 Subject: [PATCH 09/17] Renamed option --- src/core/operations/Lorenz.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 057f9cb3c..067ebffd2 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -89,7 +89,7 @@ class Lorenz extends Operation { "value": ["Plaintext", "ITA2"] }, { - name: "Output Format", + name: "ITA2 Format", type: "option", "value": ["5/8/9", "+/-/."] }, From db662a76623f912be7d5fdae7f75eea3f8b27067 Mon Sep 17 00:00:00 2001 From: martin gillow Date: Sat, 30 Mar 2019 10:13:25 +0000 Subject: [PATCH 10/17] Removed debug. Final testing --- src/core/operations/Lorenz.mjs | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 067ebffd2..169ef848c 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -288,7 +288,6 @@ class Lorenz extends Operation { if (lugx4.length != 26 || !re.test(lugx4) ) throw new OperationError("Χ4 custom lugs must be 26 long and can only include . or x"); if (lugx5.length != 23 || !re.test(lugx5) ) throw new OperationError("Χ5 custom lugs must be 23 long and can only include . or x"); var chosenSetting = INIT_PATTERNS["No Pattern"]; - console.log(chosenSetting); chosenSetting["S"][1] = this.readLugs(lugs1); chosenSetting["S"][2] = this.readLugs(lugs2); chosenSetting["S"][3] = this.readLugs(lugs3); @@ -301,7 +300,6 @@ class Lorenz extends Operation { chosenSetting["X"][3] = this.readLugs(lugx3); chosenSetting["X"][4] = this.readLugs(lugx4); chosenSetting["X"][5] = this.readLugs(lugx5); - console.log(chosenSetting); } else { var chosenSetting = INIT_PATTERNS[pattern]; } @@ -317,7 +315,7 @@ class Lorenz extends Operation { var letter = character.toUpperCase(); if(intype == "Plaintext") { - if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character"); + if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter); if( !figShifted && figShiftedChars.indexOf(letter) !== -1 ) { // in letters mode and next char needs to be figure shifted @@ -342,8 +340,12 @@ class Lorenz extends Operation { } else { - if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); - + if (validITA2.indexOf(letter) === -1) { + var errltr = letter; + if(errltr=="\n") errltr = "Carriage Return"; + if(errltr==" ") errltr = "Space"; + throw new OperationError("Invalid ITA2 character : "+errltr); + } return letter; } @@ -355,28 +357,30 @@ class Lorenz extends Operation { // Receive input should always be ITA2 ita2 = Array.prototype.map.call(input, function(character) { var letter = character.toUpperCase(); - if (validITA2.indexOf(letter) === -1) throw new OperationError("Invalid ITA2 character"); + if (validITA2.indexOf(letter) === -1) { + var errltr = letter; + if(errltr=="\n") errltr = "Carriage Return"; + if(errltr==" ") errltr = "Space"; + throw new OperationError("Invalid ITA2 character : "+errltr); + } return letter; }); } const ita2Input = ita2.join(""); - console.log(ita2Input); var thisPsi = []; var thisChi = []; var thisMu = []; var m61lug = muSettings[1][m61-1]; - var m37lug = 0; + var m37lug = muSettings[2][m37-1]; var p5 = [0,0,0]; const self = this; const letters = Array.prototype.map.call(ita2Input, function(character) { const letter = character.toUpperCase(); - //console.log(s1+' '+s2+' '+s3+' '+s4+' '+s5+' : '+m37+' '+m61+' : '+x1+' '+x2+' '+x3+' '+x4+' '+x5); - var x2bptr = x2+1; if(x2bptr==32) x2bptr=1; var s1bptr = s1+1; @@ -403,8 +407,6 @@ class Lorenz extends Operation { muSettings[2][m37-1] ]; - console.log(letter + ' + ' + self.REVERSE_ITA2_TABLE[thisPsi.join("")] + ' + ' + self.REVERSE_ITA2_TABLE[thisChi.join("")]); - if (typeof ITA2_TABLE[letter] == "undefined") { return ""; } @@ -436,15 +438,17 @@ class Lorenz extends Operation { p5[2] = p5[1]; p5[1] = p5[0]; - p5[0] = ITA2_TABLE[letter][4]; - console.log('p5='+ITA2_TABLE[letter]+' ('+letter+') = '+p5[0]); + if(mode=="Send") { + p5[0] = ITA2_TABLE[letter][4]; + } else { + p5[0] = xorSum[4]; + } // Limitations here if(model=='SZ42a') { // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position lim = chiSettings[2][x2bptr-1]; if(kt) { - console.log('lim='+lim+', p5-2='+p5[2]); if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 } @@ -453,8 +457,7 @@ class Lorenz extends Operation { totalmotor = 0; } else { totalmotor = 1; - } - console.log('BM='+basicmotor+', LM='+lim+', TM='+totalmotor); + } } else if(model=='SZ42b') { // Chi 2 one back + Psi 1 one back. @@ -465,7 +468,6 @@ class Lorenz extends Operation { if(kt) { if(lim==p5[2]) { lim=0; } else { lim=1; } //p5 back 2 } - console.log('BM='+basicmotor+', LM='+lim); // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] if(basicmotor==0 && lim==1) { totalmotor = 0; @@ -476,7 +478,6 @@ class Lorenz extends Operation { } else if(model=="SZ40") { // SZ40 totalmotor = basicmotor; - console.log('TM='+basicmotor); } else { throw new OperationError("Lorenz model type not recognised"); } From 23ddb87c9f3b768fa5f877feedce4487e8fbe5d9 Mon Sep 17 00:00:00 2001 From: martin gillow Date: Sat, 30 Mar 2019 13:02:14 +0000 Subject: [PATCH 11/17] Fixed code spacing and formatting --- src/core/operations/Lorenz.mjs | 921 ++++++++++++++++----------------- 1 file changed, 458 insertions(+), 463 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 169ef848c..c1b29fdd8 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -1,6 +1,6 @@ /** * Emulation of the Lorenz SZ40/42a/42b cipher attachment. - * + * * @author VirtualColossus [martin@virtualcolossus.co.uk] * @copyright Crown Copyright 2019 * @license Apache-2.0 @@ -36,26 +36,26 @@ class Lorenz extends Operation { name: "Wheel Pattern", type: "argSelector", "value": [ - { - name: "KH Pattern", - off: [19,20,21,22,23,24,25,26,27,28,29,30], - }, - { - name: "ZMUG Pattern", - off: [19,20,21,22,23,24,25,26,27,28,29,30] - }, - { - name: "BREAM Pattern", - off: [19,20,21,22,23,24,25,26,27,28,29,30] - }, - { - name: "No Pattern", - off: [19,20,21,22,23,24,25,26,27,28,29,30] - }, - { - name: "Custom", - on: [19,20,21,22,23,24,25,26,27,28,29,30] - } + { + name: "KH Pattern", + off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] + }, + { + name: "ZMUG Pattern", + off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] + }, + { + name: "BREAM Pattern", + off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] + }, + { + name: "No Pattern", + off: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] + }, + { + name: "Custom", + on: [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] + } ] }, { @@ -66,16 +66,16 @@ class Lorenz extends Operation { name: "Mode", type: "argSelector", "value": [ - { - name: "Send", - on: [4], - off: [5] - }, - { - name: "Receive", - off: [4], - on: [5] - } + { + name: "Send", + on: [4], + off: [5] + }, + { + name: "Receive", + off: [4], + on: [5] + } ] }, { @@ -89,129 +89,129 @@ class Lorenz extends Operation { "value": ["Plaintext", "ITA2"] }, { - name: "ITA2 Format", - type: "option", + name: "ITA2 Format", + type: "option", "value": ["5/8/9", "+/-/."] }, { - name: "Ψ1 start (1-43)", - type: "number", - "value": 1 + name: "Ψ1 start (1-43)", + type: "number", + "value": 1 }, { - name: "Ψ2 start (1-47)", - type: "number", - "value": 1 + name: "Ψ2 start (1-47)", + type: "number", + "value": 1 }, { - name: "Ψ3 start (1-51)", - type: "number", - "value": 1 + name: "Ψ3 start (1-51)", + type: "number", + "value": 1 }, { - name: "Ψ4 start (1-53)", - type: "number", - "value": 1 + name: "Ψ4 start (1-53)", + type: "number", + "value": 1 }, { - name: "Ψ5 start (1-59)", - type: "number", - "value": 1 + name: "Ψ5 start (1-59)", + type: "number", + "value": 1 }, { - name: "Μ37 start (1-37)", - type: "number", - "value": 1 + name: "Μ37 start (1-37)", + type: "number", + "value": 1 }, { - name: "Μ61 start (1-61)", - type: "number", - "value": 1 + name: "Μ61 start (1-61)", + type: "number", + "value": 1 }, { - name: "Χ1 start (1-41)", - type: "number", - "value": 1 + name: "Χ1 start (1-41)", + type: "number", + "value": 1 }, { - name: "Χ2 start (1-31)", - type: "number", - "value": 1 + name: "Χ2 start (1-31)", + type: "number", + "value": 1 }, { - name: "Χ3 start (1-29)", - type: "number", - "value": 1 + name: "Χ3 start (1-29)", + type: "number", + "value": 1 }, { - name: "Χ4 start (1-26)", - type: "number", - "value": 1 + name: "Χ4 start (1-26)", + type: "number", + "value": 1 }, { - name: "Χ5 start (1-23)", - type: "number", - "value": 1 + name: "Χ5 start (1-23)", + type: "number", + "value": 1 }, { - name: "Ψ1 lugs (43)", - type: "string", - value: ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x" + name: "Ψ1 lugs (43)", + type: "string", + value: ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x" }, { - name: "Ψ2 lugs (47)", - type: "string", - value: ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x" + name: "Ψ2 lugs (47)", + type: "string", + value: ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x" }, { - name: "Ψ3 lugs (51)", - type: "string", - value: ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x" + name: "Ψ3 lugs (51)", + type: "string", + value: ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x" }, { - name: "Ψ4 lugs (53)", - type: "string", - value: ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x." + name: "Ψ4 lugs (53)", + type: "string", + value: ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x." }, { - name: "Ψ5 lugs (59)", - type: "string", - value: "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x." + name: "Ψ5 lugs (59)", + type: "string", + value: "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x." }, { - name: "Μ37 lugs (37)", - type: "string", - value: "x.x.x.x.x.x...x.x.x...x.x.x...x.x...." + name: "Μ37 lugs (37)", + type: "string", + value: "x.x.x.x.x.x...x.x.x...x.x.x...x.x...." }, { - name: "Μ61 lugs (61)", - type: "string", - value: ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx..." + name: "Μ61 lugs (61)", + type: "string", + value: ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx..." }, { - name: "Χ1 lugs (41)", - type: "string", - value: ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx.." + name: "Χ1 lugs (41)", + type: "string", + value: ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx.." }, { - name: "Χ2 lugs (31)", - type: "string", - value: "x..xxx...x.xxxx..xx..x..xx.xx.." + name: "Χ2 lugs (31)", + type: "string", + value: "x..xxx...x.xxxx..xx..x..xx.xx.." }, { - name: "Χ3 lugs (29)", - type: "string", - value: "..xx..x.xxx...xx...xx..xx.xx." + name: "Χ3 lugs (29)", + type: "string", + value: "..xx..x.xxx...xx...xx..xx.xx." }, { - name: "Χ4 lugs (26)", - type: "string", - value: "xx..x..xxxx..xx.xxx....x.." + name: "Χ4 lugs (26)", + type: "string", + value: "xx..x..xxxx..xx.xxx....x.." }, { - name: "Χ5 lugs (23)", - type: "string", - value: "xx..xx....xxxx.x..x.x.." + name: "Χ5 lugs (23)", + type: "string", + value: "xx..xx....xxxx.x..x.x.." } ]; } @@ -222,330 +222,325 @@ class Lorenz extends Operation { * @returns {string} */ run(input, args) { - + const model = args[0], - pattern = args[1], - kt = args[2], - mode = args[3], - format = args[6]; - - var intype = args[4], - outtype = args[5], - s1 = args[7], - s2 = args[8], - s3 = args[9], - s4 = args[10], - s5 = args[11], - m37 = args[12], - m61 = args[13], - x1 = args[14], - x2 = args[15], - x3 = args[16], - x4 = args[17], - x5 = args[18], - lugs1 = args[19], - lugs2 = args[20], - lugs3 = args[21], - lugs4 = args[22], - lugs5 = args[23], - lugm37 = args[24], - lugm61 = args[25], - lugx1 = args[26], - lugx2 = args[27], - lugx3 = args[28], - lugx4 = args[29], - lugx5 = args[30], - figShifted = false; + pattern = args[1], + kt = args[2], + mode = args[3], + format = args[6]; + + let intype = args[4], + outtype = args[5], + s1 = args[7], + s2 = args[8], + s3 = args[9], + s4 = args[10], + s5 = args[11], + m37 = args[12], + m61 = args[13], + x1 = args[14], + x2 = args[15], + x3 = args[16], + x4 = args[17], + x5 = args[18], + lugs1 = args[19], + lugs2 = args[20], + lugs3 = args[21], + lugs4 = args[22], + lugs5 = args[23], + lugm37 = args[24], + lugm61 = args[25], + lugx1 = args[26], + lugx2 = args[27], + lugx3 = args[28], + lugx4 = args[29], + lugx5 = args[30], + figShifted = false; this.reverseTable(); - - if (s1<1 || s1>43) throw new OperationError("Ψ1 start must be between 1 and 43"); - if (s2<1 || s2>47) throw new OperationError("Ψ2 start must be between 1 and 47"); - if (s3<1 || s3>51) throw new OperationError("Ψ3 start must be between 1 and 51"); - if (s4<1 || s4>53) throw new OperationError("Ψ4 start must be between 1 and 53"); - if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59"); - if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37"); - if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61"); - if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41"); - if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31"); - if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29"); - if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26"); - if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23"); + + if (s1<1 || s1>43) throw new OperationError("Ψ1 start must be between 1 and 43"); + if (s2<1 || s2>47) throw new OperationError("Ψ2 start must be between 1 and 47"); + if (s3<1 || s3>51) throw new OperationError("Ψ3 start must be between 1 and 51"); + if (s4<1 || s4>53) throw new OperationError("Ψ4 start must be between 1 and 53"); + if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59"); + if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37"); + if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61"); + if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41"); + if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31"); + if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29"); + if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26"); + if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23"); // Initialise chosen wheel pattern - if(pattern=="Custom") { - var re = new RegExp("^[\.xX]*$"); - if (lugs1.length != 43 || !re.test(lugs1) ) throw new OperationError("Ψ1 custom lugs must be 43 long and can only include . or x "); - if (lugs2.length != 47 || !re.test(lugs2) ) throw new OperationError("Ψ2 custom lugs must be 47 long and can only include . or x"); - if (lugs3.length != 51 || !re.test(lugs3) ) throw new OperationError("Ψ3 custom lugs must be 51 long and can only include . or x"); - if (lugs4.length != 53 || !re.test(lugs4) ) throw new OperationError("Ψ4 custom lugs must be 53 long and can only include . or x"); - if (lugs5.length != 59 || !re.test(lugs5) ) throw new OperationError("Ψ5 custom lugs must be 59 long and can only include . or x"); - if (lugm37.length != 37 || !re.test(lugm37) ) throw new OperationError("M37 custom lugs must be 37 long and can only include . or x"); - if (lugm61.length != 61 || !re.test(lugm61) ) throw new OperationError("M61 custom lugs must be 61 long and can only include . or x"); - if (lugx1.length != 41 || !re.test(lugx1) ) throw new OperationError("Χ1 custom lugs must be 41 long and can only include . or x"); - if (lugx2.length != 31 || !re.test(lugx2) ) throw new OperationError("Χ2 custom lugs must be 31 long and can only include . or x"); - if (lugx3.length != 29 || !re.test(lugx3) ) throw new OperationError("Χ3 custom lugs must be 29 long and can only include . or x"); - if (lugx4.length != 26 || !re.test(lugx4) ) throw new OperationError("Χ4 custom lugs must be 26 long and can only include . or x"); - if (lugx5.length != 23 || !re.test(lugx5) ) throw new OperationError("Χ5 custom lugs must be 23 long and can only include . or x"); - var chosenSetting = INIT_PATTERNS["No Pattern"]; - chosenSetting["S"][1] = this.readLugs(lugs1); - chosenSetting["S"][2] = this.readLugs(lugs2); - chosenSetting["S"][3] = this.readLugs(lugs3); - chosenSetting["S"][4] = this.readLugs(lugs4); - chosenSetting["S"][5] = this.readLugs(lugs5); - chosenSetting["M"][1] = this.readLugs(lugm37); - chosenSetting["M"][2] = this.readLugs(lugm61); - chosenSetting["X"][1] = this.readLugs(lugx1); - chosenSetting["X"][2] = this.readLugs(lugx2); - chosenSetting["X"][3] = this.readLugs(lugx3); - chosenSetting["X"][4] = this.readLugs(lugx4); - chosenSetting["X"][5] = this.readLugs(lugx5); + let chosenSetting = ''; + if (pattern === "Custom") { + let re = new RegExp("^[.xX]*$"); + if (lugs1.length !== 43 || !re.test(lugs1)) throw new OperationError("Ψ1 custom lugs must be 43 long and can only include . or x "); + if (lugs2.length !== 47 || !re.test(lugs2)) throw new OperationError("Ψ2 custom lugs must be 47 long and can only include . or x"); + if (lugs3.length !== 51 || !re.test(lugs3)) throw new OperationError("Ψ3 custom lugs must be 51 long and can only include . or x"); + if (lugs4.length !== 53 || !re.test(lugs4)) throw new OperationError("Ψ4 custom lugs must be 53 long and can only include . or x"); + if (lugs5.length !== 59 || !re.test(lugs5)) throw new OperationError("Ψ5 custom lugs must be 59 long and can only include . or x"); + if (lugm37.length !== 37 || !re.test(lugm37)) throw new OperationError("M37 custom lugs must be 37 long and can only include . or x"); + if (lugm61.length !== 61 || !re.test(lugm61)) throw new OperationError("M61 custom lugs must be 61 long and can only include . or x"); + if (lugx1.length !== 41 || !re.test(lugx1)) throw new OperationError("Χ1 custom lugs must be 41 long and can only include . or x"); + if (lugx2.length !== 31 || !re.test(lugx2)) throw new OperationError("Χ2 custom lugs must be 31 long and can only include . or x"); + if (lugx3.length !== 29 || !re.test(lugx3)) throw new OperationError("Χ3 custom lugs must be 29 long and can only include . or x"); + if (lugx4.length !== 26 || !re.test(lugx4)) throw new OperationError("Χ4 custom lugs must be 26 long and can only include . or x"); + if (lugx5.length !== 23 || !re.test(lugx5)) throw new OperationError("Χ5 custom lugs must be 23 long and can only include . or x"); + chosenSetting = INIT_PATTERNS["No Pattern"]; + chosenSetting.S[1] = this.readLugs(lugs1); + chosenSetting.S[2] = this.readLugs(lugs2); + chosenSetting.S[3] = this.readLugs(lugs3); + chosenSetting.S[4] = this.readLugs(lugs4); + chosenSetting.S[5] = this.readLugs(lugs5); + chosenSetting.M[1] = this.readLugs(lugm37); + chosenSetting.M[2] = this.readLugs(lugm61); + chosenSetting.X[1] = this.readLugs(lugx1); + chosenSetting.X[2] = this.readLugs(lugx2); + chosenSetting.X[3] = this.readLugs(lugx3); + chosenSetting.X[4] = this.readLugs(lugx4); + chosenSetting.X[5] = this.readLugs(lugx5); } else { - var chosenSetting = INIT_PATTERNS[pattern]; + chosenSetting = INIT_PATTERNS[pattern]; } - var chiSettings = chosenSetting["X"]; // Pin settings for Chi links (X) - var psiSettings = chosenSetting["S"]; // Pin settings for Psi links (S) - var muSettings = chosenSetting["M"]; // Pin settings for Motor links (M) - - var ita2 = ""; - if(mode == "Send") { - - // Convert input text to ITA2 (including figure/letter shifts) - ita2 = Array.prototype.map.call(input, function(character) { - var letter = character.toUpperCase(); - - if(intype == "Plaintext") { - if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter); - - if( !figShifted && figShiftedChars.indexOf(letter) !== -1 ) { - // in letters mode and next char needs to be figure shifted - figShifted = true; - return "55" + figShiftArr[letter]; - } else if( figShifted ) { - // in figures mode and next char needs to be letter shifted - if(letter=="\n") return "34"; - if(letter=="\r") return "4"; - if( figShiftedChars.indexOf(letter) === -1 ) { - figShifted = false; - return "88" + letter; - } else { - return figShiftArr[letter]; - } - - } else { - if(letter=="\n") return "34"; - if(letter=="\r") return "4"; + var chiSettings = chosenSetting.X; // Pin settings for Chi links (X) + var psiSettings = chosenSetting.S; // Pin settings for Psi links (S) + var muSettings = chosenSetting.M; // Pin settings for Motor links (M) + + let ita2 = ""; + if (mode === "Send") { + + // Convert input text to ITA2 (including figure/letter shifts) + ita2 = Array.prototype.map.call(input, function(character) { + let letter = character.toUpperCase(); + + if (intype === "Plaintext") { + if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter); + + if(!figShifted && figShiftedChars.indexOf(letter) !== -1) { + // in letters mode and next char needs to be figure shifted + figShifted = true; + return "55" + figShiftArr[letter]; + } else if (figShifted) { + // in figures mode and next char needs to be letter shifted + if (letter==="\n") return "34"; + if (letter==="\r") return "4"; + if (figShiftedChars.indexOf(letter) === -1) { + figShifted = false; + return "88" + letter; + } else { + return figShiftArr[letter]; + } + + } else { + if (letter==="\n") return "34"; + if (letter==="\r") return "4"; return letter; - } + } - } else { + } else { - if (validITA2.indexOf(letter) === -1) { - var errltr = letter; - if(errltr=="\n") errltr = "Carriage Return"; - if(errltr==" ") errltr = "Space"; + if (validITA2.indexOf(letter) === -1) { + let errltr = letter; + if (errltr==="\n") errltr = "Carriage Return"; + if (errltr===" ") errltr = "Space"; throw new OperationError("Invalid ITA2 character : "+errltr); - } - return letter; + } + return letter; - } + } - }); + }); } else { - // Receive input should always be ITA2 - ita2 = Array.prototype.map.call(input, function(character) { - var letter = character.toUpperCase(); - if (validITA2.indexOf(letter) === -1) { + // Receive input should always be ITA2 + ita2 = Array.prototype.map.call(input, function(character) { + let letter = character.toUpperCase(); + if (validITA2.indexOf(letter) === -1) { var errltr = letter; - if(errltr=="\n") errltr = "Carriage Return"; - if(errltr==" ") errltr = "Space"; + if (errltr==="\n") errltr = "Carriage Return"; + if(errltr===" ") errltr = "Space"; throw new OperationError("Invalid ITA2 character : "+errltr); } - return letter; - }); + return letter; + }); } const ita2Input = ita2.join(""); - var thisPsi = []; - var thisChi = []; - var thisMu = []; - var m61lug = muSettings[1][m61-1]; - var m37lug = muSettings[2][m37-1]; - var p5 = [0,0,0]; + let thisPsi = []; + let thisChi = []; + let m61lug = muSettings[1][m61-1]; + let m37lug = muSettings[2][m37-1]; + let p5 = [0,0,0]; const self = this; const letters = Array.prototype.map.call(ita2Input, function(character) { const letter = character.toUpperCase(); - var x2bptr = x2+1; - if(x2bptr==32) x2bptr=1; - var s1bptr = s1+1; - if(s1bptr==44) s1bptr=1; + let x2bptr = x2+1; + if (x2bptr===32) x2bptr=1; + let s1bptr = s1+1; + if (s1bptr===44) s1bptr=1; thisChi = [ - chiSettings[1][x1-1], - chiSettings[2][x2-1], - chiSettings[3][x3-1], - chiSettings[4][x4-1], - chiSettings[5][x5-1] - ]; - - thisPsi = [ - psiSettings[1][s1-1], - psiSettings[2][s2-1], - psiSettings[3][s3-1], - psiSettings[4][s4-1], - psiSettings[5][s5-1] - ]; - - thisMu = [ - muSettings[1][m61-1], - muSettings[2][m37-1] - ]; + chiSettings[1][x1-1], + chiSettings[2][x2-1], + chiSettings[3][x3-1], + chiSettings[4][x4-1], + chiSettings[5][x5-1] + ]; + + thisPsi = [ + psiSettings[1][s1-1], + psiSettings[2][s2-1], + psiSettings[3][s3-1], + psiSettings[4][s4-1], + psiSettings[5][s5-1] + ]; if (typeof ITA2_TABLE[letter] == "undefined") { return ""; } - var xorSum = []; + let xorSum = []; for(var i=0;i<=4;i++) { xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i]; } const resultStr = xorSum.join(""); // Move Chi wheels one back after each letter - if(--x1 < 1) x1 = 41; - if(--x2 < 1) x2 = 31; - if(--x3 < 1) x3 = 29; - if(--x4 < 1) x4 = 26; - if(--x5 < 1) x5 = 23; + if (--x1 < 1) x1 = 41; + if (--x2 < 1) x2 = 31; + if (--x3 < 1) x3 = 29; + if (--x4 < 1) x4 = 26; + if (--x5 < 1) x5 = 23; // Motor wheel (61 pin) also moves one each letter - if(--m61 < 1) m61 = 61; + if (--m61 < 1) m61 = 61; // If M61 is set, we also move M37 - if(m61lug == 1) { - if(--m37 < 1) m37 = 37; + if (m61lug === 1) { + if (--m37 < 1) m37 = 37; } - var basicmotor = m37lug; - var totalmotor = basicmotor; - var lim = 0; + let basicmotor = m37lug; + let totalmotor = basicmotor; + let lim = 0; p5[2] = p5[1]; p5[1] = p5[0]; - if(mode=="Send") { + if (mode==="Send") { p5[0] = ITA2_TABLE[letter][4]; } else { p5[0] = xorSum[4]; } - // Limitations here - if(model=='SZ42a') { - // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position - lim = chiSettings[2][x2bptr-1]; - if(kt) { - if(lim==p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 - } + // Limitations here + if (model==='SZ42a') { + // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position + lim = chiSettings[2][x2bptr-1]; + if(kt) { + if (lim===p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 + } - // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] - if(basicmotor==0 && lim==1) { - totalmotor = 0; - } else { - totalmotor = 1; - } - - } else if(model=='SZ42b') { - // Chi 2 one back + Psi 1 one back. - const x2b1lug = chiSettings[2][x2bptr-1]; - const s1b1lug = psiSettings[1][s1bptr-1]; - lim = 1; - if(x2b1lug==s1b1lug) lim=0; - if(kt) { - if(lim==p5[2]) { lim=0; } else { lim=1; } //p5 back 2 - } - // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] - if(basicmotor==0 && lim==1) { - totalmotor = 0; - } else { - totalmotor = 1; - } - - } else if(model=="SZ40") { - // SZ40 - totalmotor = basicmotor; - } else { - throw new OperationError("Lorenz model type not recognised"); - } - - // increment Psi wheels when current totalmotor active - if(totalmotor == 1) { - if(--s1 < 1) s1 = 43; - if(--s2 < 1) s2 = 47; - if(--s3 < 1) s3 = 51; - if(--s4 < 1) s4 = 53; - if(--s5 < 1) s5 = 59; - } + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if (basicmotor===0 && lim===1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if(model=='SZ42b') { + // Chi 2 one back + Psi 1 one back. + const x2b1lug = chiSettings[2][x2bptr-1]; + const s1b1lug = psiSettings[1][s1bptr-1]; + lim = 1; + if (x2b1lug===s1b1lug) lim=0; + if(kt) { + if (lim===p5[2]) { lim=0; } else { lim=1; } //p5 back 2 + } + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] + if (basicmotor===0 && lim===1) { + totalmotor = 0; + } else { + totalmotor = 1; + } + + } else if (model==="SZ40") { + // SZ40 + totalmotor = basicmotor; + } else { + throw new OperationError("Lorenz model type not recognised"); + } + + // increment Psi wheels when current totalmotor active + if (totalmotor === 1) { + if(--s1 < 1) s1 = 43; + if(--s2 < 1) s2 = 47; + if(--s3 < 1) s3 = 51; + if(--s4 < 1) s4 = 53; + if(--s5 < 1) s5 = 59; + } m61lug = muSettings[1][m61-1]; m37lug = muSettings[2][m37-1]; - var rtnstr = self.REVERSE_ITA2_TABLE[resultStr]; - if(format=="5/8/9") { - if(rtnstr=="+") rtnstr="5"; - if(rtnstr=="-") rtnstr="8"; - if(rtnstr==".") rtnstr="9"; + let rtnstr = self.REVERSE_ITA2_TABLE[resultStr]; + if (format==="5/8/9") { + if (rtnstr==="+") rtnstr="5"; + if (rtnstr==="-") rtnstr="8"; + if (rtnstr===".") rtnstr="9"; } return rtnstr; }); - var ita2output = letters.join(""); - var output = ""; - - if(mode == "Receive") { + let ita2output = letters.join(""); + let output = ""; - figShifted = false; + if (mode === "Receive") { - // Convert output ITA2 to plaintext (including figure/letter shifts) - const out = Array.prototype.map.call(ita2output, function(letter) { - - if(outtype == "Plaintext") { + figShifted = false; - if( letter == "5" || letter == "+" ) { - figShifted = true; - return; - } else if( letter == "8" || letter == "-" ) { - figShifted = false; - return; - } else if( letter == "9" ) { - return " "; - } else if( letter == "3" ) { + // Convert output ITA2 to plaintext (including figure/letter shifts) + const out = Array.prototype.map.call(ita2output, function(letter) { + + if (outtype === "Plaintext") { + + if (letter === "5" || letter === "+") { + figShifted = true; + return; + } else if (letter === "8" || letter === "-") { + figShifted = false; + return; + } else if (letter === "9") { + return " "; + } else if (letter === "3") { return "\n"; - } else if( letter == "4" ) { + } else if (letter === "4") { return ""; } - if(figShifted) { - return self.REVERSE_FIGSHIFT_TABLE[letter]; - } else { - return letter; - } + if (figShifted) { + return self.REVERSE_FIGSHIFT_TABLE[letter]; + } else { + return letter; + } - } else { - return letter; - } + } else { + return letter; + } - }); - output = out.join(""); + }); + output = out.join(""); - } else { - output = ita2output; - } + } else { + output = ita2output; + } return output; @@ -563,20 +558,20 @@ class Lorenz extends Operation { this.REVERSE_ITA2_TABLE[code] = letter; } for (const letter in figShiftArr) { - const ltr = figShiftArr[letter]; - this.REVERSE_FIGSHIFT_TABLE[ltr] = letter; + const ltr = figShiftArr[letter]; + this.REVERSE_FIGSHIFT_TABLE[ltr] = letter; } } readLugs(lugstr) { - var arr = Array.prototype.map.call(lugstr, function(lug) { - if(lug==".") { - return 0; - } else { - return 1; - } - }); - return arr; + let arr = Array.prototype.map.call(lugstr, function(lug) { + if(lug==".") { + return 0; + } else { + return 1; + } + }); + return arr; } } @@ -625,118 +620,118 @@ const validITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./"; const figShiftedChars = "1234567890+-'()/:=?,." const figShiftArr = { - "1" : "Q", - "2" : "W", - "3" : "E", - "4" : "R", - "5" : "T", - "6" : "Y", - "7" : "U", - "8" : "I", - "9" : "O", - "0" : "P", - " " : "9", - "-" : "A", - "?" : "B", - ":" : "C", - "#" : "D", - "%" : "F", - "@" : "G", - "£" : "H", - "(" : "K", - ")" : "L", - "." : "M", - "," : "N", - "'" : "S", - "=" : "V", - "/" : "X", - "+" : "Z", - "\n" : "3", - "\r" : "4" + "1": "Q", + "2": "W", + "3": "E", + "4": "R", + "5": "T", + "6": "Y", + "7": "U", + "8": "I", + "9": "O", + "0": "P", + " ": "9", + "-": "A", + "?": "B", + ":": "C", + "#": "D", + "%": "F", + "@": "G", + "£": "H", + "(": "K", + ")": "L", + ".": "M", + ",": "N", + "'": "S", + "=": "V", + "/": "X", + "+": "Z", + "\n": "3", + "\r": "4" }; const INIT_PATTERNS = { - "No Pattern" : { - "X" : { - 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - }, - "S" : { - 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 3 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 4 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 5 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - }, - "M" : { - 1 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 2 : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + "No Pattern": { + "X": { + 1: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "S": { + 1: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 3: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 4: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 5: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }, + "M": { + 1: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + 2: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] } }, - "KH Pattern" : { - "X" : { - 1 : [0,1,0,0,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0], - 2 : [1,0,0,1,1,1,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,0,1,1,0,0], - 3 : [0,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,0], - 4 : [1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,1,0,0], - 5 : [1,1,0,0,1,1,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,0,0] - }, - "S" : { - 1 : [0,1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,1], - 2 : [0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1], - 3 : [0,1,0,1,0,1,0,0,1,1,1,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1], - 4 : [0,1,1,0,0,0,1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0], - 5 : [1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,0,1,0] - }, + "KH Pattern": { + "X": { + 1: [0,1,0,0,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0], + 2: [1,0,0,1,1,1,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,0,1,1,0,0], + 3: [0,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,0], + 4: [1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,1,0,0], + 5: [1,1,0,0,1,1,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,0,0] + }, + "S": { + 1: [0,1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,1], + 2: [0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1], + 3: [0,1,0,1,0,1,0,0,1,1,1,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1], + 4: [0,1,1,0,0,0,1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0], + 5: [1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,0,1,0] + }, "M": { - 1 : [0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,0], - 2 : [1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0] + 1: [0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,0], + 2: [1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0] } }, - "ZMUG Pattern" : { - "X" : { - 1 : [0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,0], - 2 : [1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,1,1,0,0,0], - 3 : [0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,0,1,1,1,1,0], - 4 : [1,0,1,0,1,0,0,1,1,0,0,0,1,1,0,0,1,0,1,1,1,0,0,1,0,1], - 5 : [0,1,0,0,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,0,1], - }, - "S" : { - 1 : [1,1,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0], - 2 : [0,0,0,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1], - 3 : [0,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1], - 4 : [0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,1], - 5 : [1,0,0,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,0] - }, - "M" : { - 1 : [1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1], - 2 : [0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1] + "ZMUG Pattern": { + "X": { + 1: [0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,0], + 2: [1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,1,1,0,0,0], + 3: [0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,0,1,1,1,1,0], + 4: [1,0,1,0,1,0,0,1,1,0,0,0,1,1,0,0,1,0,1,1,1,0,0,1,0,1], + 5: [0,1,0,0,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,0,1] + }, + "S": { + 1: [1,1,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0], + 2: [0,0,0,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1], + 3: [0,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1], + 4: [0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,1], + 5: [1,0,0,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,0] + }, + "M": { + 1: [1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1], + 2: [0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1] } }, - "BREAM Pattern" : { - "X" : { - 1 : [0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0], - 2 : [0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,1,1], - 3 : [1,1,0,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,0,1,1,1,0,0], - 4 : [1,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0], - 5 : [0,1,1,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0] - }, - "S" : { - 1 : [0,0,0,1,1,1,0,0,1,1,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0], - 2 : [1,1,0,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,0], - 3 : [1,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], - 4 : [0,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1], - 5 : [1,0,1,0,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0] - }, - "M" : { - 1 : [1,0,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,1,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1,1], - 2 : [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1] + "BREAM Pattern": { + "X": { + 1: [0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0], + 2: [0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,1,1], + 3: [1,1,0,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,0,1,1,1,0,0], + 4: [1,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0], + 5: [0,1,1,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0] + }, + "S": { + 1: [0,0,0,1,1,1,0,0,1,1,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0], + 2: [1,1,0,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,0], + 3: [1,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], + 4: [0,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1], + 5: [1,0,1,0,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0] + }, + "M": { + 1: [1,0,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,1,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1,1], + 2: [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1] } } }; -export default Lorenz; +export default Lorenz; \ No newline at end of file From 4d39c3bbd2c29722dc0496d0c436252d3c225c72 Mon Sep 17 00:00:00 2001 From: martin gillow Date: Sat, 30 Mar 2019 13:42:29 +0000 Subject: [PATCH 12/17] Fixed code spacing and formatting --- src/core/operations/Lorenz.mjs | 303 +++++++++++++++++---------------- 1 file changed, 158 insertions(+), 145 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index c1b29fdd8..4d72428fe 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -227,22 +227,9 @@ class Lorenz extends Operation { pattern = args[1], kt = args[2], mode = args[3], - format = args[6]; - - let intype = args[4], + intype = args[4], outtype = args[5], - s1 = args[7], - s2 = args[8], - s3 = args[9], - s4 = args[10], - s5 = args[11], - m37 = args[12], - m61 = args[13], - x1 = args[14], - x2 = args[15], - x3 = args[16], - x4 = args[17], - x5 = args[18], + format = args[6], lugs1 = args[19], lugs2 = args[20], lugs3 = args[21], @@ -254,7 +241,20 @@ class Lorenz extends Operation { lugx2 = args[27], lugx3 = args[28], lugx4 = args[29], - lugx5 = args[30], + lugx5 = args[30]; + + let s1 = args[7], + s2 = args[8], + s3 = args[9], + s4 = args[10], + s5 = args[11], + m37 = args[12], + m61 = args[13], + x1 = args[14], + x2 = args[15], + x3 = args[16], + x4 = args[17], + x5 = args[18], figShifted = false; this.reverseTable(); @@ -273,9 +273,9 @@ class Lorenz extends Operation { if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23"); // Initialise chosen wheel pattern - let chosenSetting = ''; + let chosenSetting = ""; if (pattern === "Custom") { - let re = new RegExp("^[.xX]*$"); + const re = new RegExp("^[.xX]*$"); if (lugs1.length !== 43 || !re.test(lugs1)) throw new OperationError("Ψ1 custom lugs must be 43 long and can only include . or x "); if (lugs2.length !== 47 || !re.test(lugs2)) throw new OperationError("Ψ2 custom lugs must be 47 long and can only include . or x"); if (lugs3.length !== 51 || !re.test(lugs3)) throw new OperationError("Ψ3 custom lugs must be 51 long and can only include . or x"); @@ -304,21 +304,21 @@ class Lorenz extends Operation { } else { chosenSetting = INIT_PATTERNS[pattern]; } - var chiSettings = chosenSetting.X; // Pin settings for Chi links (X) - var psiSettings = chosenSetting.S; // Pin settings for Psi links (S) - var muSettings = chosenSetting.M; // Pin settings for Motor links (M) + const chiSettings = chosenSetting.X; // Pin settings for Chi links (X) + const psiSettings = chosenSetting.S; // Pin settings for Psi links (S) + const muSettings = chosenSetting.M; // Pin settings for Motor links (M) let ita2 = ""; if (mode === "Send") { // Convert input text to ITA2 (including figure/letter shifts) ita2 = Array.prototype.map.call(input, function(character) { - let letter = character.toUpperCase(); - + const letter = character.toUpperCase(); + if (intype === "Plaintext") { if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter); - if(!figShifted && figShiftedChars.indexOf(letter) !== -1) { + if (!figShifted && figShiftedChars.indexOf(letter) !== -1) { // in letters mode and next char needs to be figure shifted figShifted = true; return "55" + figShiftArr[letter]; @@ -357,11 +357,11 @@ class Lorenz extends Operation { // Receive input should always be ITA2 ita2 = Array.prototype.map.call(input, function(character) { - let letter = character.toUpperCase(); + const letter = character.toUpperCase(); if (validITA2.indexOf(letter) === -1) { - var errltr = letter; - if (errltr==="\n") errltr = "Carriage Return"; - if(errltr===" ") errltr = "Space"; + let errltr = letter; + if (errltr==="\n") errltr = "Carriage Return"; + if (errltr===" ") errltr = "Space"; throw new OperationError("Invalid ITA2 character : "+errltr); } return letter; @@ -375,7 +375,7 @@ class Lorenz extends Operation { let thisChi = []; let m61lug = muSettings[1][m61-1]; let m37lug = muSettings[2][m37-1]; - let p5 = [0,0,0]; + const p5 = [0, 0, 0]; const self = this; const letters = Array.prototype.map.call(ita2Input, function(character) { @@ -387,18 +387,18 @@ class Lorenz extends Operation { if (s1bptr===44) s1bptr=1; thisChi = [ - chiSettings[1][x1-1], - chiSettings[2][x2-1], - chiSettings[3][x3-1], - chiSettings[4][x4-1], + chiSettings[1][x1-1], + chiSettings[2][x2-1], + chiSettings[3][x3-1], + chiSettings[4][x4-1], chiSettings[5][x5-1] ]; thisPsi = [ - psiSettings[1][s1-1], - psiSettings[2][s2-1], - psiSettings[3][s3-1], - psiSettings[4][s4-1], + psiSettings[1][s1-1], + psiSettings[2][s2-1], + psiSettings[3][s3-1], + psiSettings[4][s4-1], psiSettings[5][s5-1] ]; @@ -406,8 +406,8 @@ class Lorenz extends Operation { return ""; } - let xorSum = []; - for(var i=0;i<=4;i++) { + const xorSum = []; + for (let i=0;i<=4;i++) { xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i]; } const resultStr = xorSum.join(""); @@ -427,7 +427,7 @@ class Lorenz extends Operation { if (--m37 < 1) m37 = 37; } - let basicmotor = m37lug; + const basicmotor = m37lug; let totalmotor = basicmotor; let lim = 0; @@ -440,28 +440,38 @@ class Lorenz extends Operation { } // Limitations here - if (model==='SZ42a') { + if (model==="SZ42a") { // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position lim = chiSettings[2][x2bptr-1]; - if(kt) { - if (lim===p5[2]) { lim = 0; } else { lim=1; } //p5 back 2 + if (kt) { + //p5 back 2 + if (lim===p5[2]) { + lim = 0; + } else { + lim=1; + } } - + // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] if (basicmotor===0 && lim===1) { totalmotor = 0; } else { totalmotor = 1; - } + } - } else if(model=='SZ42b') { + } else if (model==="SZ42b") { // Chi 2 one back + Psi 1 one back. const x2b1lug = chiSettings[2][x2bptr-1]; const s1b1lug = psiSettings[1][s1bptr-1]; lim = 1; if (x2b1lug===s1b1lug) lim=0; - if(kt) { - if (lim===p5[2]) { lim=0; } else { lim=1; } //p5 back 2 + if (kt) { + //p5 back 2 + if (lim===p5[2]) { + lim=0; + } else { + lim=1; + } } // If basic motor = 0 and limitation = 1, Total motor = 0 [no move], otherwise, total motor = 1 [move] if (basicmotor===0 && lim===1) { @@ -479,11 +489,11 @@ class Lorenz extends Operation { // increment Psi wheels when current totalmotor active if (totalmotor === 1) { - if(--s1 < 1) s1 = 43; - if(--s2 < 1) s2 = 47; - if(--s3 < 1) s3 = 51; - if(--s4 < 1) s4 = 53; - if(--s5 < 1) s5 = 59; + if (--s1 < 1) s1 = 43; + if (--s2 < 1) s2 = 47; + if (--s3 < 1) s3 = 51; + if (--s4 < 1) s4 = 53; + if (--s5 < 1) s5 = 59; } m61lug = muSettings[1][m61-1]; @@ -498,7 +508,7 @@ class Lorenz extends Operation { return rtnstr; }); - let ita2output = letters.join(""); + const ita2output = letters.join(""); let output = ""; if (mode === "Receive") { @@ -507,7 +517,7 @@ class Lorenz extends Operation { // Convert output ITA2 to plaintext (including figure/letter shifts) const out = Array.prototype.map.call(ita2output, function(letter) { - + if (outtype === "Plaintext") { if (letter === "5" || letter === "+") { @@ -531,7 +541,7 @@ class Lorenz extends Operation { return letter; } - } else { + } else { return letter; } @@ -563,13 +573,16 @@ class Lorenz extends Operation { } } + /** + * Read lugs settings - convert to 0|1 + */ readLugs(lugstr) { - let arr = Array.prototype.map.call(lugstr, function(lug) { - if(lug==".") { + const arr = Array.prototype.map.call(lugstr, function(lug) { + if (lug===".") { return 0; } else { return 1; - } + } }); return arr; } @@ -617,121 +630,121 @@ const ITA2_TABLE = { const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-'()/:=?,. \n\r"; const validITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./"; -const figShiftedChars = "1234567890+-'()/:=?,." +const figShiftedChars = "1234567890+-'()/:=?,."; const figShiftArr = { - "1": "Q", - "2": "W", - "3": "E", - "4": "R", - "5": "T", - "6": "Y", - "7": "U", - "8": "I", - "9": "O", - "0": "P", - " ": "9", - "-": "A", - "?": "B", - ":": "C", - "#": "D", - "%": "F", - "@": "G", - "£": "H", - "(": "K", - ")": "L", - ".": "M", - ",": "N", - "'": "S", - "=": "V", - "/": "X", - "+": "Z", - "\n": "3", - "\r": "4" + "1": "Q", + "2": "W", + "3": "E", + "4": "R", + "5": "T", + "6": "Y", + "7": "U", + "8": "I", + "9": "O", + "0": "P", + " ": "9", + "-": "A", + "?": "B", + ":": "C", + "#": "D", + "%": "F", + "@": "G", + "£": "H", + "(": "K", + ")": "L", + ".": "M", + ",": "N", + "'": "S", + "=": "V", + "/": "X", + "+": "Z", + "\n": "3", + "\r": "4" }; const INIT_PATTERNS = { "No Pattern": { "X": { - 1: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 2: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 3: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 4: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 5: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - }, + 1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, "S": { - 1: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 2: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 3: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 4: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 5: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - }, + 1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, "M": { - 1: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - 2: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] } }, "KH Pattern": { "X": { - 1: [0,1,0,0,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0], - 2: [1,0,0,1,1,1,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,0,1,1,0,0], - 3: [0,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,0], - 4: [1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,1,0,0], - 5: [1,1,0,0,1,1,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,0,0] - }, + 1: [0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0], + 2: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0], + 3: [0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0], + 4: [1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0], + 5: [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0] + }, "S": { - 1: [0,1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,1], - 2: [0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1], - 3: [0,1,0,1,0,1,0,0,1,1,1,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1], - 4: [0,1,1,0,0,0,1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0], - 5: [1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,0,0,1,1,0,1,0,0,1,0] - }, + 1: [0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1], + 2: [0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1], + 3: [0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1], + 4: [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], + 5: [1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0] + }, "M": { - 1: [0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,0], - 2: [1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0] + 1: [0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0], + 2: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0] } }, "ZMUG Pattern": { "X": { - 1: [0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,0], - 2: [1,1,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,1,1,0,0,0], - 3: [0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,0,1,1,1,1,0], - 4: [1,0,1,0,1,0,0,1,1,0,0,0,1,1,0,0,1,0,1,1,1,0,0,1,0,1], - 5: [0,1,0,0,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,0,1] - }, + 1: [0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0], + 2: [1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0], + 3: [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0], + 4: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1], + 5: [0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1] + }, "S": { - 1: [1,1,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0], - 2: [0,0,0,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,1,1], - 3: [0,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1], - 4: [0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,0,1], - 5: [1,0,0,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,1,1,0] - }, + 1: [1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0], + 2: [0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1], + 3: [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1], + 4: [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1], + 5: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0] + }, "M": { - 1: [1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1], - 2: [0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1] + 1: [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1], + 2: [0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1] } }, "BREAM Pattern": { "X": { - 1: [0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0], - 2: [0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,1,1], - 3: [1,1,0,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,0,1,1,1,0,0], - 4: [1,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0], - 5: [0,1,1,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,1,0] - }, + 1: [0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0], + 2: [0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1], + 3: [1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0], + 4: [1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0], + 5: [0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0] + }, "S": { - 1: [0,0,0,1,1,1,0,0,1,1,1,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0], - 2: [1,1,0,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,0], - 3: [1,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1], - 4: [0,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1], - 5: [1,0,1,0,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0] - }, + 1: [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0], + 2: [1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0], + 3: [1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], + 4: [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1], + 5: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] + }, "M": { - 1: [1,0,0,0,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,1,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1,1], - 2: [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1] + 1: [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1], + 2: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1] } } }; -export default Lorenz; \ No newline at end of file +export default Lorenz; From 8ece8ebec2a6e150465fa8b7c61c23f1725cc183 Mon Sep 17 00:00:00 2001 From: Martin Gillow Date: Mon, 1 Apr 2019 13:40:53 +0100 Subject: [PATCH 13/17] Updated description --- src/core/operations/Lorenz.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 4d72428fe..56eada603 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -22,8 +22,8 @@ class Lorenz extends Operation { this.name = "Lorenz"; this.module = "Default"; - this.description = "Enciphers characters using the World War 2 German Lorenz SZ cipher attachment."; - this.infoURL = "https://lorenz.virtualcolossus.co.uk"; + this.description = "The Lorenz SZ40/42 cipher attachment was a WW2 German rotor cipher machine with twelve rotors which attached in-line between remote teleprinters.

It used the Vernam cipher with two groups of five rotors (named the psi(ψ) wheels and chi(χ) wheels at Bletchley Park) to create two pseudorandom streams of five bits, encoded in ITA2, which were XOR added to the plaintext. Two other rotors, dubbed the mu(μ) or motor wheels, could hold up the stepping of the psi wheels meaning they stepped intermittently.

Each rotor has a different number of cams/lugs around their circumference which could be set active or inactive changing the key stream.

Three models of the Lorenz are emulated, SZ40, SZ42a and SZ42b and three example wheel patterns (the lug settings) are included (KH, ZMUG & BREAM) with the option to set a custom set using the letter 'x' for active or '.' for an inactive lug.

The input can either be plaintext or ITA2 when sending and ITA2 when receiving.

To learn more, Virtual Lorenz, an online, browser based simulation of the Lorenz SZ40/42 is available at https://lorenz.virtualcolossus.co.uk."; + this.infoURL = "https://en.wikipedia.org/wiki/Lorenz_cipher"; this.inputType = "string"; this.outputType = "string"; this.args = [ From 55eae9910f652eb95cc463a70d9123b160b4e2f5 Mon Sep 17 00:00:00 2001 From: VirtualColossus Date: Tue, 29 Oct 2019 21:39:29 +0000 Subject: [PATCH 14/17] Tidied run function, added some tests --- src/core/operations/Lorenz.mjs | 237 ++++++++++++++++-------------- tests/operations/index.mjs | 1 + tests/operations/tests/Lorenz.mjs | 94 ++++++++++++ 3 files changed, 218 insertions(+), 114 deletions(-) create mode 100644 tests/operations/tests/Lorenz.mjs diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 56eada603..7ca58f830 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -254,8 +254,7 @@ class Lorenz extends Operation { x2 = args[15], x3 = args[16], x4 = args[17], - x5 = args[18], - figShifted = false; + x5 = args[18]; this.reverseTable(); @@ -308,68 +307,8 @@ class Lorenz extends Operation { const psiSettings = chosenSetting.S; // Pin settings for Psi links (S) const muSettings = chosenSetting.M; // Pin settings for Motor links (M) - let ita2 = ""; - if (mode === "Send") { - - // Convert input text to ITA2 (including figure/letter shifts) - ita2 = Array.prototype.map.call(input, function(character) { - const letter = character.toUpperCase(); - - if (intype === "Plaintext") { - if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter); - - if (!figShifted && figShiftedChars.indexOf(letter) !== -1) { - // in letters mode and next char needs to be figure shifted - figShifted = true; - return "55" + figShiftArr[letter]; - } else if (figShifted) { - // in figures mode and next char needs to be letter shifted - if (letter==="\n") return "34"; - if (letter==="\r") return "4"; - if (figShiftedChars.indexOf(letter) === -1) { - figShifted = false; - return "88" + letter; - } else { - return figShiftArr[letter]; - } - - } else { - if (letter==="\n") return "34"; - if (letter==="\r") return "4"; - return letter; - } - - } else { - - if (validITA2.indexOf(letter) === -1) { - let errltr = letter; - if (errltr==="\n") errltr = "Carriage Return"; - if (errltr===" ") errltr = "Space"; - throw new OperationError("Invalid ITA2 character : "+errltr); - } - return letter; - - } - - }); - - } else { - - // Receive input should always be ITA2 - ita2 = Array.prototype.map.call(input, function(character) { - const letter = character.toUpperCase(); - if (validITA2.indexOf(letter) === -1) { - let errltr = letter; - if (errltr==="\n") errltr = "Carriage Return"; - if (errltr===" ") errltr = "Space"; - throw new OperationError("Invalid ITA2 character : "+errltr); - } - return letter; - }); - - } - - const ita2Input = ita2.join(""); + // Convert input text to ITA2 (including figure/letter shifts) + const ita2Input = this.convertToITA2(input, intype, mode); let thisPsi = []; let thisChi = []; @@ -381,6 +320,7 @@ class Lorenz extends Operation { const letters = Array.prototype.map.call(ita2Input, function(character) { const letter = character.toUpperCase(); + // Store lugs used in limitations, need these later let x2bptr = x2+1; if (x2bptr===32) x2bptr=1; let s1bptr = s1+1; @@ -406,13 +346,18 @@ class Lorenz extends Operation { return ""; } + // The encipher calculation + + // We calculate Bitwise XOR for each of the 5 bits across our input ( K XOR Psi XOR Chi ) const xorSum = []; for (let i=0;i<=4;i++) { xorSum[i] = ITA2_TABLE[letter][i] ^ thisPsi[i] ^ thisChi[i]; } const resultStr = xorSum.join(""); - // Move Chi wheels one back after each letter + // Wheel movement + + // Chi wheels always move one back after each letter if (--x1 < 1) x1 = 41; if (--x2 < 1) x2 = 31; if (--x3 < 1) x3 = 29; @@ -427,6 +372,8 @@ class Lorenz extends Operation { if (--m37 < 1) m37 = 37; } + // Psi wheels only move sometimes, dependent on M37 current setting and limitations + const basicmotor = m37lug; let totalmotor = basicmotor; let lim = 0; @@ -441,7 +388,7 @@ class Lorenz extends Operation { // Limitations here if (model==="SZ42a") { - // Chi 2 one back lim - The active character of chi 2 (2nd Chi wheel) in the previous position + // Chi 2 one back lim - The active character of Chi 2 (2nd Chi wheel) in the previous position lim = chiSettings[2][x2bptr-1]; if (kt) { //p5 back 2 @@ -481,13 +428,13 @@ class Lorenz extends Operation { } } else if (model==="SZ40") { - // SZ40 + // SZ40 - just move based on the M37 motor wheel totalmotor = basicmotor; } else { throw new OperationError("Lorenz model type not recognised"); } - // increment Psi wheels when current totalmotor active + // Move the Psi wheels when current totalmotor active if (totalmotor === 1) { if (--s1 < 1) s1 = 43; if (--s2 < 1) s2 = 47; @@ -501,58 +448,16 @@ class Lorenz extends Operation { let rtnstr = self.REVERSE_ITA2_TABLE[resultStr]; if (format==="5/8/9") { - if (rtnstr==="+") rtnstr="5"; - if (rtnstr==="-") rtnstr="8"; - if (rtnstr===".") rtnstr="9"; + if (rtnstr==="+") rtnstr="5"; // + or 5 used to represent figure shift + if (rtnstr==="-") rtnstr="8"; // - or 8 used to represent letter shift + if (rtnstr===".") rtnstr="9"; // . or 9 used to represent space } return rtnstr; }); const ita2output = letters.join(""); - let output = ""; - - if (mode === "Receive") { - - figShifted = false; - - // Convert output ITA2 to plaintext (including figure/letter shifts) - const out = Array.prototype.map.call(ita2output, function(letter) { - - if (outtype === "Plaintext") { - - if (letter === "5" || letter === "+") { - figShifted = true; - return; - } else if (letter === "8" || letter === "-") { - figShifted = false; - return; - } else if (letter === "9") { - return " "; - } else if (letter === "3") { - return "\n"; - } else if (letter === "4") { - return ""; - } - - - if (figShifted) { - return self.REVERSE_FIGSHIFT_TABLE[letter]; - } else { - return letter; - } - - } else { - return letter; - } - - }); - output = out.join(""); - - } else { - output = ita2output; - } - return output; + return this.convertFromITA2(ita2output, outtype, mode); } @@ -587,6 +492,109 @@ class Lorenz extends Operation { return arr; } + /** + * Convert input plaintext to ITA2 + */ + convertToITA2(input, intype, mode) { + let result = ""; + let figShifted = false; + + for (const character of input) { + const letter = character.toUpperCase(); + + // Convert input text to ITA2 (including figure/letter shifts) + if (intype === "ITA2" || mode === "Receive") { + if (validITA2.indexOf(letter) === -1) { + let errltr = letter; + if (errltr==="\n") errltr = "Carriage Return"; + if (errltr===" ") errltr = "Space"; + throw new OperationError("Invalid ITA2 character : "+errltr); + } + result += letter; + } else { + if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter); + + if (!figShifted && figShiftedChars.indexOf(letter) !== -1) { + // in letters mode and next char needs to be figure shifted + figShifted = true; + result += "55" + figShiftArr[letter]; + } else if (figShifted) { + // in figures mode and next char needs to be letter shifted + if (letter==="\n") { + result += "34"; + } else if (letter==="\r") { + result += "4"; + } else if (figShiftedChars.indexOf(letter) === -1) { + figShifted = false; + result += "88" + letter; + } else { + result += figShiftArr[letter]; + } + + } else { + if (letter==="\n") { + result += "34"; + } else if (letter==="\r") { + result += "4"; + } else { + result += letter; + } + } + + } + + } + + return result; + } + + /** + * Convert final result ITA2 to plaintext + */ + convertFromITA2(input, outtype, mode) { + let result = ""; + let figShifted = false; + for (const letter of input) { + if (mode === "Receive") { + + // Convert output ITA2 to plaintext (including figure/letter shifts) + if (outtype === "Plaintext") { + + if (letter === "5" || letter === "+") { + figShifted = true; + } else if (letter === "8" || letter === "-") { + figShifted = false; + } else if (letter === "9") { + result += " "; + } else if (letter === "3") { + result += "\n"; + } else if (letter === "4") { + result += ""; + } else if (letter === "/") { + result += "/"; + } else { + + if (figShifted) { + result += this.REVERSE_FIGSHIFT_TABLE[letter]; + } else { + result += letter; + } + + } + + } else { + result += letter; + } + + } else { + result += letter; + } + } + + return result; + + } + } const ITA2_TABLE = { @@ -651,6 +659,7 @@ const figShiftArr = { "%": "F", "@": "G", "£": "H", + "": "J", "(": "K", ")": "L", ".": "M", diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index d64a77377..8c39a179f 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -91,6 +91,7 @@ import "./tests/Protobuf.mjs"; import "./tests/ParseSSHHostKey.mjs"; import "./tests/DefangIP.mjs"; import "./tests/ParseUDP.mjs"; +import "./tests/Lorenz.mjs"; // Cannot test operations that use the File type yet // import "./tests/SplitColourChannels.mjs"; diff --git a/tests/operations/tests/Lorenz.mjs b/tests/operations/tests/Lorenz.mjs new file mode 100644 index 000000000..c93808e6c --- /dev/null +++ b/tests/operations/tests/Lorenz.mjs @@ -0,0 +1,94 @@ +/** + * Lorenz SZ40/42a/42b machine tests. + * @author VirtualColossus + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + // Simple test first - plain text to ITA2 + name: "Lorenz SZ40: no pattern, plain text", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "HELLO9WORLD55N889THIS9IS9A9TEST9MESSAGE55M", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ40", "No Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, + { + // KH Pattern + name: "Lorenz SZ40: KH pattern, plain text, all 1s", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "VIC3TS/CUJA/3II9W9JWDI5DAFXT4SOIF3999IZD9T", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ40", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, + { + // KH Pattern, Random Start + name: "Lorenz SZ40: KH pattern, plain text, random start", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "KGZP5ONYCHNNOXS9SN45MIE3SC3DJBZVJUOE5SLVGI", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ40", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, + { + // ZMUG Pattern, Random Start + name: "Lorenz SZ40: ZMUG pattern, plain text, random start", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "IQVPAANDCA3CHDNO3V/CZQ/BTPZIKW8YAAQXQGLDMV", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ40", "ZMUG Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, + { + // Bream Pattern, Random Start + name: "Lorenz SZ40: Bream pattern, plain text, random start", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "/89OALRPJEZQGOO84WOEQZ/I9NBRZOQPBTANC8E/GK", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ40", "BREAM Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, + { + // KH Pattern, all 1s + name: "Lorenz SZ42a: KH pattern, plain text, all 1s", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ42a", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, + { + // KH Pattern, all 1s + name: "Lorenz SZ42a: KH pattern, plain text, all 1s", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ42a", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, +]); \ No newline at end of file From ab524fff15aa8cec74986c952f508fd35d7c97da Mon Sep 17 00:00:00 2001 From: VirtualColossus Date: Tue, 29 Oct 2019 21:52:18 +0000 Subject: [PATCH 15/17] Mixed tabs & spaces --- tests/operations/tests/Lorenz.mjs | 100 +++++++++++++++--------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/tests/operations/tests/Lorenz.mjs b/tests/operations/tests/Lorenz.mjs index c93808e6c..6e18ea9f8 100644 --- a/tests/operations/tests/Lorenz.mjs +++ b/tests/operations/tests/Lorenz.mjs @@ -7,88 +7,88 @@ import TestRegister from "../../lib/TestRegister.mjs"; TestRegister.addTests([ - { - // Simple test first - plain text to ITA2 - name: "Lorenz SZ40: no pattern, plain text", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "HELLO9WORLD55N889THIS9IS9A9TEST9MESSAGE55M", - recipeConfig: [ + { + // Simple test first - plain text to ITA2 + name: "Lorenz SZ40: no pattern, plain text", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "HELLO9WORLD55N889THIS9IS9A9TEST9MESSAGE55M", + recipeConfig: [ { "op": "Lorenz", "args": ["SZ40", "No Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] - }, - { - // KH Pattern - name: "Lorenz SZ40: KH pattern, plain text, all 1s", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "VIC3TS/CUJA/3II9W9JWDI5DAFXT4SOIF3999IZD9T", - recipeConfig: [ + }, + { + // KH Pattern + name: "Lorenz SZ40: KH pattern, plain text, all 1s", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "VIC3TS/CUJA/3II9W9JWDI5DAFXT4SOIF3999IZD9T", + recipeConfig: [ { "op": "Lorenz", "args": ["SZ40", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] - }, - { - // KH Pattern, Random Start - name: "Lorenz SZ40: KH pattern, plain text, random start", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "KGZP5ONYCHNNOXS9SN45MIE3SC3DJBZVJUOE5SLVGI", - recipeConfig: [ + }, + { + // KH Pattern, Random Start + name: "Lorenz SZ40: KH pattern, plain text, random start", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "KGZP5ONYCHNNOXS9SN45MIE3SC3DJBZVJUOE5SLVGI", + recipeConfig: [ { "op": "Lorenz", "args": ["SZ40", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] - }, - { - // ZMUG Pattern, Random Start - name: "Lorenz SZ40: ZMUG pattern, plain text, random start", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "IQVPAANDCA3CHDNO3V/CZQ/BTPZIKW8YAAQXQGLDMV", - recipeConfig: [ + }, + { + // ZMUG Pattern, Random Start + name: "Lorenz SZ40: ZMUG pattern, plain text, random start", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "IQVPAANDCA3CHDNO3V/CZQ/BTPZIKW8YAAQXQGLDMV", + recipeConfig: [ { "op": "Lorenz", "args": ["SZ40", "ZMUG Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] - }, - { - // Bream Pattern, Random Start - name: "Lorenz SZ40: Bream pattern, plain text, random start", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "/89OALRPJEZQGOO84WOEQZ/I9NBRZOQPBTANC8E/GK", - recipeConfig: [ + }, + { + // Bream Pattern, Random Start + name: "Lorenz SZ40: Bream pattern, plain text, random start", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "/89OALRPJEZQGOO84WOEQZ/I9NBRZOQPBTANC8E/GK", + recipeConfig: [ { "op": "Lorenz", "args": ["SZ40", "BREAM Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 20, 40, 3, 9, 27, 36, 4, 1, 9, 14, 21, 8, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] - }, - { - // KH Pattern, all 1s - name: "Lorenz SZ42a: KH pattern, plain text, all 1s", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K", - recipeConfig: [ + }, + { + // KH Pattern, all 1s + name: "Lorenz SZ42a: KH pattern, plain text, all 1s", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K", + recipeConfig: [ { "op": "Lorenz", "args": ["SZ42a", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] - }, - { - // KH Pattern, all 1s - name: "Lorenz SZ42a: KH pattern, plain text, all 1s", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K", - recipeConfig: [ + }, + { + // KH Pattern, all 1s + name: "Lorenz SZ42a: KH pattern, plain text, all 1s", + input: "HELLO WORLD, THIS IS A TEST MESSAGE.", + expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K", + recipeConfig: [ { "op": "Lorenz", "args": ["SZ42a", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] - }, -]); \ No newline at end of file + } +]); From c0e02451a1602564e306d2aeabd7d32e248c0574 Mon Sep 17 00:00:00 2001 From: VirtualColossus Date: Thu, 31 Oct 2019 07:28:33 +0000 Subject: [PATCH 16/17] Fixed bug using KT option, added tests --- src/core/operations/Lorenz.mjs | 10 +++++----- tests/operations/tests/Lorenz.mjs | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/core/operations/Lorenz.mjs b/src/core/operations/Lorenz.mjs index 7ca58f830..07f5d5582 100644 --- a/src/core/operations/Lorenz.mjs +++ b/src/core/operations/Lorenz.mjs @@ -381,15 +381,15 @@ class Lorenz extends Operation { p5[2] = p5[1]; p5[1] = p5[0]; if (mode==="Send") { - p5[0] = ITA2_TABLE[letter][4]; + p5[0] = parseInt(ITA2_TABLE[letter][4], 10); } else { - p5[0] = xorSum[4]; + p5[0] = parseInt(xorSum[4], 10); } // Limitations here if (model==="SZ42a") { // Chi 2 one back lim - The active character of Chi 2 (2nd Chi wheel) in the previous position - lim = chiSettings[2][x2bptr-1]; + lim = parseInt(chiSettings[2][x2bptr-1], 10); if (kt) { //p5 back 2 if (lim===p5[2]) { @@ -408,8 +408,8 @@ class Lorenz extends Operation { } else if (model==="SZ42b") { // Chi 2 one back + Psi 1 one back. - const x2b1lug = chiSettings[2][x2bptr-1]; - const s1b1lug = psiSettings[1][s1bptr-1]; + const x2b1lug = parseInt(chiSettings[2][x2bptr-1], 10); + const s1b1lug = parseInt(psiSettings[1][s1bptr-1], 10); lim = 1; if (x2b1lug===s1b1lug) lim=0; if (kt) { diff --git a/tests/operations/tests/Lorenz.mjs b/tests/operations/tests/Lorenz.mjs index 6e18ea9f8..52705f694 100644 --- a/tests/operations/tests/Lorenz.mjs +++ b/tests/operations/tests/Lorenz.mjs @@ -90,5 +90,30 @@ TestRegister.addTests([ "args": ["SZ42a", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] } ] + }, + { + // KH Pattern, Full Test on real message + name: "Lorenz SZ42a: Receive, KH pattern, ITA2 output", + input: "J3KF+LXT/.+YTMLE/RFVC-SE///4GYX3Q.Z3GVWKWDVAPURPYL/.UYAI.EOW3ZBVVAQRTO/PACJ.NLVLZYYNTU.IDCPKTEZOSWCOBNWFJ+UAKE+WU-JMWYWLXRM+M/HV+TVTC-FOGN3QZG4J.VLM/KK+OVC/YIWTSZUDTSY+3LCCHZADQ-3VBXKEOCSO/+ZBFN34-F.+4UVFVLIP4KFGRBFIVFFJX/FKFSHJ.VUJVWXE+LFAICDYX3EZD33U+GSOGXPAXHTJSNUQI+PXS3JRG+-U+YZITF/SM4LIDPSYMVJM/BL/YHDGBG/UI+EM.JEMX.YQNUWTLAUCLUSDMZGXCQ3CPPCCYLTJC4KXB--G4VGQ4J.EYTEVSG33DVLVPDGNOGAJOUWGFY4KGO-4+IRKDPGDHGBQLFSS/YDP/FM-/BANLERZEMT.U3XZA43RGYD+-J4VYRTONRYF/OI4Y+I3LXUFAHGRT.RXCO3HKCQIML.VHVIGHBWBTU3RZFN.J.WGNLSGLYBJT+TPM-RHHMXTNDSVUO3W/4ORZ4UY.LA-XZYVLCZROMPM3RYSLUD-SNQQA+RK/UV4K/GOSSMJRGIZYPO+BEEB+OEWAWKYXW.-NKUQERUM-PA4WFNKU-Q-LNC.D-A3C.FB.RFOGZHUWTEAYB3HNHCEW.N33QEEVUEC3OOR4BRNLH/IF3+DJJ3S3J4XA+Z3SMT/K4L-IDLQWCLMQ3TO3PNYVCGZCXUMSSBH.BWMGGTIYSC/UBX/PE+3IZZ.Z/CCWLSL+4/4+IET/ELBCBDAM4ELKDAGB3O.3J+IEQQJ.U.VSAQSAYZAU+3YOZWPPPV/YOVOE/P/E4UOZYK4PE3A.ETZGFBCZE.4WA3PSDR3XMLJLH+S3UWOA.T-RID-MA.CVZGLNYK4U.HBPSA+3U+BLSGS/FNRXMOMEBBABIPOAGDWA-4T/B.L.HDSAJE.HE-4FZW+SDBAYCNBTEODDALCMIG-QNM+-PEFC+ABNQ-MVT3-GHKAN/ENZLPMJRVRB+4NBCRTFDVNLRTPIGIEZGSPUXMW3WJQTOEV+WA-HJZLX-JQID-X++FFGKCTO.3.F+JIISVTXKC+..YM/SOQUIAS-IAGJJPRYLLT.EJBJAMRP+MS-ZRUVLBBE-UNYQGBBHEB+QCHYYHVN.NHKS-YG3BNZKQJBO-FQ.SZB/JRFILGUZUZVCOVGULEKU4/HRBGYIZVLCM3/ONJ-OBIRSCT+IZCB-TTZMDQWQUCIVTGTTYNEOTTORM-FSKS3WJWL/ZXOCOCYGC.BRIRKXK.FLJUSP/-G.WP.MMVHBYREWQZZAN/BKSEYDBGXAUV+NUKUKIKIGS+VO-4EY/GWI+SGJOJCBYGGMY4+/EMGULCSC-Y+CXLIECYC-+-ZXHSPOTFGFDWIFT-4XXDDLMMKT433WH/BX-OILWDJC/FFE-ZYH3C4GI4T/3KUJQ4YNBQWXWB-RM.Q3GG/4Z-AIGW4GYYEBXRJHXQA..-.G/3W/-LVS+4GS-+FRYIOFYGUK-FEYA4J-ZB-MSPAM/WLLJ3GFMJP/GGF-C+O-KQ.K4PWVL+3O.LX4TUD+Y+QOO3GTJT+.MR-4JSRXD-X4SCIDIVLCDEGSOZOGWXQZOZ.3PPQ4ZYXKL+QETCM/3/--CHG4+W.BNHTB+Z-NZCO+QEB+-/FNJ+NSHTO+CW.CM/VHIM-S.3VAFDJ3MEH.G+NQFDCUSK+MCKDLEC-TFWSYBQSWE4UOQOXY-E.ESE4OLJQOBUQZUSLRWV-AVOYX3CKS3ZFUAQAWESYMXQV/4MOXORAVKOIELRXCSRAEU/KEFDQWQ-BWEXGALS/.JLQ/CEKT-4C+TWDNGST-UQ-ERBP.YZ-ZH/Q3ITMN-O3P/JBEVZUOY4CTNY4PKCB3YIW/+BOKDEZE.VCTROQDTAXI3VKGYQVOKSCXPDDAD4DLTELK.GDDLTRPXORSFTDOGB.-NQJHNM/4/JOTIVGOQF+FC.GDX4DMT.UBRVUIBCHGLDBZSFSICVVAF4TN.BMAP-IQR-LBCQ/TTHH", + expectedOutput: "XWOLLE9WI9R99AUCH9BLEIBEN955Z88KR99GWFRL5X89FUES959WPYP9QXT9QIPQ9V9AACQEM9959AA899QEE9959AA8999AN99OB5M89SUEDW/ST5V9AA8GEHEIME9KOMMANDOSACHE5AA89959AA89NUR9ZUR9PERSOENLICHENSINTERRICHTUNG5N889WEITERGABE9VERBOTEN5MA9AA8LAGEBERICHT9VOM99GSEPMM98NN99VOM9959EPMRM9QORT9AA889KATEN9NN9KAT9NN9KARTEN9959Q9C9QSVPP9PPP9A9MA98889ROEM959QM89WESTEN9959C899AOK999L9U9C88889ROEMS59QWM89A5M89K5MCMA989PANZERUNTERSTUEZ9NN9PANZSRUNTERSTUETZTESFEINDANGRIFFE99GEGEN9EIGENE9STUETZPU9NKTFRONT9NAHMEN9O4D9ELSTER5N89SOHL5N89RAU9NN9RAU9N9UND9BAD9BRAMBACH95K9WR8889NN9995KWT88SKM9BFO9HOF5LM89NEUE9STUETZPUNKTFRONT9B99DIESER9ORT5M89UEBRIGE9CORPSFRONT9BEIDERSEITIGE9AUFKLAERUNGSTAETIGKEI5M9DIESER9ORT5M89I/BRIGE9KORPSFRONT9BEIDERSEITIGE9AUFKLAERUNGSTAETIGKEI5MA99A8STELWV5M89ROEM959QEM89A5M8K5MMA989ZUNEHMENDER9FEINDDRUCK9IM9RAUXSN9UND99W99BAERNAU95K9T889NN9959KWT889KM9SW9MARIENBAD5LM889FEINDAFGRIF9F99VON99SO99GEGEN9PAULUSBRUNN5M899LAGE9DORT9UNGEKL4ERT5M89SCHWACHE99EIGENEN9SICHERUNGEN9DURCH9FEIND9AUS99SCHAENWAWDE9UND9WOSANT995K9Y89KM9SO99TACHAU5L89NACH9O99ZURUECKGEWOFNN9TURUEIKGEWORFEN5M89FEIND99MIT9INF9UND9PZ5M89IN9PEISSIGKAU9UND9WLAD9NS9DAHENTEN5M89EIGENE9SICHERANGEN9IN9MOLGAU959A89DRI9UND9WLAD9N993AHENTEN5M89EIGENE9SIC4ERUNGENSIGKAU9UND9WLAD9N99DAHENTEN5M89EUGENE9SICHERUNGEN9IN9MOLGAU959A89DRISSGLOBEN959A89WURKAU5M89IM9A9SNN9IM9RAUM99TAUS99PANZERUNTERSTUETZTE99FEINDANGRIFFE5MA99AA899A5X8O5M8K5M99QC9MA9989UEBER9ISAR9MIT9INF9UND9PZ5M89UEBERBESETZTEJ9FEIND9STIESZ99UEBER9S9NN9UEBER99VILSA9BSCHNITT9VOR9UND9NAHXS9AUNKIRCHEN959A89ALDERSBACH959A89EGGERSDORF995KWP889KM9W9P49SAU5LMA9A88ROEM9959IWM89A5MLK5MCMA989DWP889KM9W9PASSAU5LMASA88ROEM9959IWM89A5MLK5MCMA989DER9ZWISCHEN9PLATTLING9UND9LANDAI9FU9NN3/UF99BREITER9FRONT99UEBER9DIE9ISAR99UEBERB99NNN9UEBER5ESETZTE99FEIND9DRUECKTE9EIGENEN9LINIE5N89TROTZ9HIFTIGEN9WIDERST4F3ES5N89AUN9VISLABSCHNITT9ZUREUCK585M89FEINDPANZER9N9NN9IN9ARTOFJFN9IN9ARNTORF959KQT889KM9SO9LANDAU5B89UND99N9ROTTESDORF599IN9ARNZORZ959KQT889KM9SO9LANDAU5L89UND99N9ROTTESDORF59KI89KM9S9LANDAUGWMA59A89ROEM959QEM8939NN9959A899ROEM9959QK4OLE", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ42a", "KH Pattern", false, "Receive", "Plaintext", "ITA2", "5/8/9", 12, 12, 41, 45, 17, 12, 3, 11, 31, 29, 12, 23, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] + }, + { + // ZMUG Pattern, Full Test, Receive + name: "Lorenz SZ42b: Receive, ZMUG pattern, KT-Schalte, Plaintext output", + input: "YQPLQQX4OJGFOKBXROZVPBVIJOXSMQSMTMHX8VSBBMIHKJTYKR4ANTQRPCJXR3YE8KVLDN8SQN4VCJQUW3BB4HWEXRD4LUJNF99DV5FLQ4IRANWRCLYX//J8YSIWO44LCPTCBKX4TZGBPYHCE/FBJ4DSBFF5YLOVPBSRUDQULTTO9BYLLUCRGTM/VXQCS8XUDLY/5O3TPSYFQ89RQRGG/IEOKULB8MHQQBHIWRW38W5XSPT9YF8WJGN3HMEBY8XKQW/3BC888Q3JC/K8SOXJWONNQCM8Z4UQQQGE8RL3GXZ3YI4O/RBCF5JXJE5W5GJAT9/9XP9V8SFZLKUBUPD4HXABGLB8D3E4YTERP3GGISVNYHOL3BQVJUOFEBZMYHBKFGPWEOGGMFGF/EVGWT584T8BMURIBSIBELCANKT/VXHUHONHFPJ/OBCQGCQPFQSQW3GEFCQKY9Z4/KVIQJPJQ4ZQJZP/PEIHQG4H99B58HD5/XCLRBPXMR8P84CMHO5RYODKY94NINO4OGY8TOF9BD9EPD5U3P9KMJ/WBXX9CO9SHMK5KHQFA9BE35R4OSAPCAXZ9SALUKVPVVYB8MGGK3XSVLKGUT/8JVIF5DSDUQT3ZKZTICJTSGXVZAZ4WWGAMOFWUN94OZR4Y8AVLGZHOV/UHCURM5RQPKDCEMRBWLKYLTTGGE8ZIVP4HJMVW5HWKOHRZ4OIUL5OZJOVHL9AQUZA93F3H9QNS5VZYZXUM8AD3RZC9CQ5B//4J8/B35XVB9MHMYQSVQPFWSXWEDU5NHXBSO/W/NBW3V/KO5VHIZQRZOKIJSV4G9Y/H3FIYLBH5/XA3AYRPUREKAQL5WTXJ4EK3EAYQ8GIDXTBXMUFUGKZHZZZPYAQMQOXZAGKP4SPIEIKVUPVPRVRSXSDRJSS3XM5KOTUVK3O435VB93H4HB8IEXHDGCJ3VHPG48VZKB4GHRNFHDQ8LN4P9TI3VD9//LACSHQJZWK5/WLC5/PHN5JTVWAOXWX59/SIZ4ADMXO5GCMYSPNLR33CFLKGSN/ZYCFAR5I4/ZQRWCVGY9GCAA5GJCW55HXVGAKGZG/V9Q9AGB9WAVKJX9DM/FOCHWZXAVEPMKTSQJYPWCYFTH3WXZRVAFCLHFMFQUGUWDHQQSUF/QSPSY/8PWPU9B8WUXFE5IPYCSYX3FKEGXIY8DCNLOWZTU8N98ZNWL8QDP/JHTU5YNHN8OI8TMBBIUQEOVT4S/N9V//LZCQ5LN3X43LUG/KDVSOXUTKOP5VTI/OUV98ULIJW9EBVUMBYBLOIKJX/XUHHYPB/N3PEVBFJGXGO3H8VTIO9D8IV5FAL5DZDOC88WNITD/CEZOB3IS8W//ZIBFQOMG3HNUXV3YMM5QH8YYPV/EJMUCKSNRTGFHBZJFTX59CMRM/D5GVFWHF8QWPY44IKNLH8A9SMHYUNXGDJBX9PA4CJPRO4RZSPTG4SYBLHMSV/9UJPUJEPHPZWSDKMMMN/WEHOZDXBPWS3DHG9SBWFTB85HOPZYTVZ9KSBGZ8PAIGGIVXU/8YIFQGQDDDVDDV3TL8L5G9C/98CYDUGWWCGQCQLS4Y8BGSSMYLOODGA/YMRWI9LJI8TXT3ZYZ8NR/3RNDYHR9DINKB//HWPJETJ8/RFXSV/SKWEBKOMSJ9W393JH8E/G3UX/5CD35H4BZOU8GYELU4EUYNYP/UUBYQZKLIPFPOPZ8WNJ4WR5QWIZVMQ9BCVZM3MB8BES5APTTVTBSILLUQHY9X/A9FFQWR5DUMNHPUKVZDYB38ZSI3CNCZPG9C/UKYRX5YWXEIBIMCBNRPGGCZKHLNG4T/R5K4LSBZUVNGBCHPI/JUIZ/IMFXEE4KYSEMYBPWBZ/UCANCY4MPXFQB3NRZQOSLBOMD9TP3IY8RQWIEG9HG3CH8AI/GGPGLXNNV4Q/ZOMVCVS4UCQFFEMMWK/RSV8RXQQPSOT8GYAUXOUJQ9VQCHAS4FL3WAMQXARHYNEPYS5TR3/MHCUSPE33NWZ48X3J9HWEJGIKOTLKAJXXAQ5X3YVLGNSSM3XT/9E/PBTN5PHCJLWKICIHER/QQMVGAGCVTKBUL3B3GQUKLKZ38YMOOJ5DTAFZSFZLVO4UZXGNNR4SJ3JFMLKDP3MXSZXX3YVLGXF3O8H5JHBZFTOZ4JDTLQGHLD5XOBLVQI/MQXS4EJAIU/VLYIGGJWNOTTF9AEQSEEGT84GI355YLVTTDGVICR8ACXJFHPTHRG8UXCLIHMW4Z3CUV89YLL3W3HDC5HUUDJ/PUS54PIJ98IXL3SEEOWWPGFN9O9ICPG4K8558ONZOHSW/U4ZRSC4C3UOHHIEARXSCZDZM4IBDBLRI99DEKKIAYPJSOSC59XGUVKSPHV9FRE35A5SII3G3DRQDQKTSC9DNUPBXVD3ORPX9NM3BK3PB5PIWUZKNCL4I4IWVO4FE4GCZBHSZWN3GS88G884DUFDUFE9RJEEKM3AJHNSEANJWQMRP5DUXHEKDWAAQGZYUL3EXY4ALN4NR3SF5CFOTZ9FGNJDFQEZU4TTVORUVS5WIZBQLZQF5HD4TTYIRPAZDNPCIYS93ZY5QQEBTYIYCQ4AJGK83BFOIK9S5GAJCBYLKSDADHOS4/XVSHDYBFSO3FZIHHHWSJ5L4R33KCXOW8T9KFQ4C8UCOCOCKXU8JJ5R9JL88UAJQ4HXWDBQ45JGY/AYGP8PMGWWLFM/9SP5OHR3FQKDIYIAOLKWM8OT8JO4W9ET5LIZMMNJBNN/A999JNG3ALKLKEK/HWZJUC5PLAILQJ8MCOO8T3X98H4ZKFIKYUKDI4ODART/K4JZDHMBY4X/BDKOYRJ/CQKZCFFBY3494/DUFHLVYZL5VG35KFSVC9IXI4S3RB3FXBDCYYKVUUTBTEFNJVRB3H5BU9NGUGJ3FBD9OOXWRTUZ8GHAHKPNL5TTUHNGMARBKFQMKFN4ODB4Y8OKCJPFQNHIGK8WFYOHI/ZW/PMHF4JAFIAYNNPOYJY/AFTDSOPNGP8GK94X3QY4A/THAWWGH3LSRST4/AV8GY4QV53A5MRYF3K3MWK5YJAWLLYWV9U/CZN4WAV3OELTO45G5IEY4P845ZJJAYGTBHXBFE5XJ5C5FFUFXCOUSWTU/LSSQ/VWNP9BSOLUB5PLNWAZF4O8LKGTA9ZAAVRIW8CP3UFS5I5N/MNMVCRD/3AM/XUPGMJAM45AY4VDA5XY4F8ZV4NXZMPZROZ/QFPLOQ/3WSZ8/FXEJEFC9W3UJGOO4RL9FEVQL/DYDAK8JLMVPY9IPYXBX3WIYOLYB5VDUAJBKCINPZZ5843H/8ZIZCVQ4RTVCOTSATJC4ZVBXYROCDXRIPGH5/WS83Y4TAA45YBPNGFFSY3I/O3JIKWMAS9TYTY38JMIEREZWOYWT3ZYRA84IRDX93H3JJQSFL43JOLPPX3UDF59RL3ESVR8J83QKTJLSJAEQOBZ8FCLWIRBXOUXQOKQ/AE885X/VQIUFETMEUC48CJMKQIJQ9ZVPHOJMCIR93GTVYWMIYMPOWFWOL99NRTWQAQ3WKLF//F3VDQDS8HLLDRKESD89OU9PSPIXW5/TX35KZUONYTLQKMGRWTSV3/5/BJZV9MHPL5UZR4ZMJZEXUE8F8E3RVDEDGVQWENRFYBOEKQMBILPWUFXZQB9XGYOSZKS8IRL9VMH5DWE3WHY3FRR83I55XUXHBJ5BMAPOHIGHQIZ/RSSAK83AUEW4Q5DZ9WTDKRMLT9OYH/VZGXUMEOV/4PL3P/SSIHX3UQIVDVQKZWHYQGZO9NLMPRSJV8/G5FTKLJ8FSKRAOZ/FZCRJLBRIBTJPGUDLFGYBXBVMJQQA3MSHFDZE/HRUOUGYZJNNWARNXNYKAWYQQWMES8K4UCFEGHDPYD/NK/U/B84NI54QLJWW/8NTWPOS/ENS355GHATHAFKK4ONFQR/WHNY3IQTTCBWF35XYXLSOXV5AIZBIGDNFDHL5OO4H/3SJBJBPTQ/3WAAO9ZGW9GYP8/JKVZKK/O9VEMBDKIJYMMVCGODXZY3QNUB8EOWKXS3HT9OFV5JJCDC9FE3FUZJOHL4HH4PA9YFA5TI5ZHFPG/RXQ/5ZMGNSTHWZC4ZC9JA8JNHKT/HNE8CLU9QF385/HDJAEEGSKGPFRKDHEPAXDH9M8Q8KQKEGYWDI9ERQGWMDPZYS/WS9PRP3/3MUKLQIKR5V4GYHNQWTB/SZM9VPQSJZLLKIF5WC5EHTILCZ95RMOJZ89LPJMPRNZ4ERL8HXZIL5B9KEBFN4YJ4LNEQOSS5ILTYECXG/MY9MRQWHFM8QFLI8CAG3BUUG53XPH4CE8GUQKZBKLNAGWXORPFZR3V9XTLBBATUTFUPC/ULGGWLFMCSP8KUYIFXTZ8V4HUQLS9MKYMJMLF/94U3PNELHVWRMISI9QYL53O5XDSFP84VOOAYCKJE4HPG3GA8MGGZVMSBMT5KWQ9V88USEMD3T8IYMIYFENMRZURQLNCICODEG/ZW4HNTOKZMC//ZGQL/XBC8STG3RXKMCO9NSVQQ8QDFDZWNIAENP/J898ADWNHCDCIO5XT8PR4BCDDAQEJV4LGLRALWU5YUL5GBDH//4TQJHBP8JWWMVBV89E/VMRUCLXGKABKSXK5KXWF9NIZB/ADKX38LTZIUBBMWIMMNZXO/EKXEGZBQZD8CYXXRVVF3/NIDWVFYU99H5KJ9DE55N59LRTPLL9PAKPPLSRC38SEUGYSUG5GRTV/5WIDY9YBNDIS4QEBELA/4QVPMVWZG3R9HSE/ZXYK8GGHQ5WVDSYI4RZTBYMUL8QLMPB4P43Y9R3PAWWZRFNNIEXPL83DVJWL3YDG/OJ9UN5CS/L3LDTGMVHMFKZE/BD4MVKJTWFXWPR4KJXYUGIZBZZMTH/JM3MIWOV/ETI5NNOUSLUYL89G3X/TPHC3A/CTNT5HM4CX5PQDMKRSLAOFGPNVRFSE/HDZFE8LFIYM5GDMAYBVRCJCHJBDJ9YS9SLJ/LA54C5DPH8LX8Y3VLP4GROV/QIPZQDB5CS4EAKFULGLIB9XSOXKDE4OJVQXYEI8RBV9PLOT8QE5WLSXG8JW8C/5FGKUR9NHIKNLYFJNSIE8WPARBOUAMNDOKRZXNIWKF8EDD/4VIFV/4UIEVIG48/M4OLBDZKOXRO4//8XAOXY8FPVJZ/O4OWL4CIVNGMWACYCYUJJLPDS/D/KYLBBFCVRTQ/DJZ3WVQEZDVYIBOKDHCYGDP4FENMNOCYJVG/RJJVKIU4EZNQRAN9WWSGYSHZWQQWXKD5RLQDSMDW9R34CYUPW/5899KP3BJM/ZGIWMAPGYF/PYLHDXDXWUPMTNAFPZMQOQVBXRI3VL84TYQRVRVPIJTTUJ8EKOQWMRTR3QGYOBSQWWKO/V4I8S/E8XW9A3HYYVSIVFS8LTWURNZ8M5EGBCLFGC3LJLVZE8MEQNTXY3XL8YTQPA4KZCMO8OJ5RDCIELIKSANPLQAVEPE5IWXMA534XDAV9CZTCBEHVVCFAGIXS4F4KVB4K/AM/DCHYW4BTY4A954GJPQ3NAK8STGW4E/FE4L/WZZJGJPLH/MSDCMK/VQ5HLLONBWSKW3LPSPIB3BSZS8ZZVRAQPO5G5MAWGVFKJSYDBXB5KGUWQZ4FBPUQS9LBKWTQCS3RC8MVTQTTS9STDAXAQJHHZSGN/RXLODYJY8EUTA8H3IFIW5FI5UFTOPTOET8F5/MUQTONBCD3OTMS3QSV/UKAIINVWPQFNHYREGBG/XWEQN/HGMG9TRHLIIQIM5WZQDX5QEBCFRJVOO8/KS9NUJRLL8LJ/5/LH4RIJUIY4/MZT4VKPL5ITODTSAULBRRG8H945J84ABZA3JT9MFA/Z3OLMHMGLO8M8DVMAEHQJMEY3JGORHACL4BGQWCE99NIGNAOSMEI9FHIY5BVB3DR4FICF8VSI3Z/HWDAXUW8RIMJQUABTRXWOEDTIFBRFBE33RM/Y4INUYXHI9393YDIEIS9DUN/AMLN99F4LML3XOCSSCSWLK9UTIUVH4TWITVCY5XDV/59GCZHTE588MXX5EWURPG35BV8VIGNZKR5BYYRULFSVMACN3VH5P5U4SQ/KWFJPAMVFVRVPBOPB8IFKYKG5D8/E4LYAVOSNXRGIFOTAVPR/CG3YK8BBAOWO3M5V/OMIWMWVI98H5PVPDF8TZNNU4EVSYYY9YFLZPCGIOQM/IZ4HWGJ5RMT98Z/HMYXWS9JL5KNFHWO3VJXC/5IOKRAURSUTLQZGTOVGFTGZQ5HXSYF495/B9VSQBSKVSSSK49TKERKV9/YV9P/OF8MOHMT3DW4DNVN4H/M3RUDL/NCEY8PUNIJBSLL/ENHJ/QJAANL/IHZYGCR3548RIDAEJOVDE9OYJZWL5CB4VXH4ILMMBKSOZNWBCZEB3KB5VPUC/5MY3RVHB5IEJCNUNKDRLBAJRHPVCNDNMBYGJQRRRHNTZPNB3IFXN3DE8OB8WBN8U8BVY/CY5TALOLPKCQEN5NBRRXZEKLQQGYOCAM8DBXYSK8H9V5H8GBK5KR/V43YXMRAK/XCKCE99KGWIMZZCYOMJCMNFIE/ONFBORYY4DPM8CWLWR/V4F8ZMQEV/RBPXAKTEEYPD8QQ5HLCNUVMW/CC//YHPVRV5I4NQF5EMRHW4CWCJHDTPYUU3895ITSPBX8FIYHO3H/UX8Z8O/JRIGGYWLDYKEOLJJXWA8C/B4/DJIBRO5/JZD4XBGLVGSYSR8TN/U/WEM/3MMUVHGDFSSXXIYXE8Z9P59MDK5PQUQATLPNK9DKTXVYX4VZIBSKKSSQ4KN/FSYKHA8VE4YYHJMGTQWMBQPRDYK/UNNNLNCKH/UJ5CDTQ8ZWTGUV4FMKPJO/FI9S8N5PPZFVVZXPBYQUAOFBS4C5H4Z/DFTEF5K4P/VEZC3X9WJHPIZMSRZSCNUKGFSUQS3CSHSQL8AN3FZGERFOSY9SA4KURA4NWWNCJRINHI5A/H3TSJ9A/ZNLM5QFQICNRSKIKRQNA3A8WNPNLEBDB3QW9/4B5YYIIWDKG5C3/IOZXIDIFUE/NX8YTCMPGQ9YMN3AXXE85C5Y33ICVD3IXFP3AJ9UJYD/G54", + expectedOutput: "IF I SAID BLETCHLEY PARK, ENIGMA AND ALAN TURING, I WOULD THINK MANY OF YOU WOULD KNOW A LITTLE ABOUT THEM, THANKS TO THE WORK OF BOTH BLETCHLEY PARK AND RECENT FILMS SUCH AS THE IMITATION GAME. NOW, WHAT ABOUT IF I SAID COLOSSUS, TOMMY FLOWERS AND BILL TUTTE? I SUSPECT THAT VERY FEW PEOPLE, EVEN IN THE LOCAL AREA AROUND BLETCHLEY PARK AND MILTON KEYNES, WOULD BE FAMILIAR WITH THESE NAMES. COLOSSUS IS, ARGUABLY, THE WORLDS FIRST ELECTRONIC COMPUTER EVER BUILT AND ITS STORY IS EVEN MORE AMAZING THAN ENIGMA, BUT IT HAS RECEIVED SIGNIFICANTLY LESS PUBLIC RECOGNITION. MANY PEOPLE WHO HAVE HEARD OF COLOSSUS BELIEVE THAT IT IS SOMETHING TO DO WITH ENIGMA, BUT THIS IS NOT THE CASE IN FACT, IT WAS BUILT TO CRACK A HARDER AND MORE SECRETIVE DEVICE BUILT BY THE LORENZ COMPANY IN GERMANY. ADOLF HITLER, REALISING THE REQUIREMENT FOR FAST AND SECURE COMMUNICATION BETWEEN HIS HIGH COMMAND AND GENERALS IN THE FIELD, ORDERED A FORMIDABLE CIPHER ATTACHMENT WHICH COULD SEND AND RECEIVE ENCODED MESSAGES AT A MUCH HIGHER RATE THAN ENIGMA. THEY BUILT A MACHINE WHICH, RATHER THAN HAVING THREE OR FOUR WHEELS LIKE ENIGMA, HAD TWELVE WHEELS, EACH OF WHICH COULD HAVE ITS SETTINGS ALTERED TO MAKE DECIPHERING THE COMMUNICATIONS EXTREMELY DIFFICULT, IF NOT (THEY HOPED) IMPOSSIBLE. IN 1940, BLETCHLEY PARK STARTED PICKING UP NEW TRANSMISSIONS, BUT NOBODY KNEW WHAT WAS ENCIPHERING THE CODES. THESE TRANSMISSIONS WERE RECORDED AND MANUALLY TRANSCRIBED ONTO PUNCHED TAPE AND SENT ON TO BLETCHLEY PARK. FINALLY, ON 30TH AUGUST 1941, A BREAKTHROUGH WAS MADE A GERMAN OPERATOR MANUALLY TYPED OUT AND TRANSMITTED A 4000 CHARACTER ENCODED MESSAGE. UNFORTUNATELY FOR HIM, THE RECEIVING END REPLIED SORRY, SEND IT AGAIN. IT WAS STRICTLY FORBIDDEN TO SEND TWO MESSAGES WITH THE SAME SETTINGS, BUT BEING ANNOYED AT HAVING TO TYPE THIS OUT AGAIN, HE DID JUST THAT AND STARTED TYPING AGAIN. TO SAVE TIME THOUGH, HE SHORTENED SOME OF THE WORDS (JUST LIKE WE WOULD TYPE NO RATHER THAN NUMBER) BUT DOING THIS MEANT THAT BLETCHLEY PARK HAD TWO MESSAGES, BOTH SENT WITH THE SAME KEY GENERATED BY THE MACHINE BUT WITH DIFFERENT ORIGINAL TEXTS. BRIGADIER JOHN TILTMAN, A SENIOR CODE BREAKER, WORKED HARD FOR TEN DAYS AND MANAGED TO SUCCESSFULLY SPLIT THESE MESSAGES BACK INTO GERMAN. MORE IMPORTANTLY, HE ALSO WORKED OUT THE ORIGINAL KEY STRING WHICH WAS GENERATED BY THIS NEW UNKNOWN MACHINE. VERY LITTLE PROGRESS WAS MADE TO CRACK THIS CODE, UNTIL THE KEY AND MESSAGES ENDED UP ON THE DESK OF A NEW MATHEMATICIAN BY THE NAME OF BILL TUTTE, WHO HAD JUST RECENTLY JOINED BLETCHLEY PARK. AFTER WEEKS OF PAINSTAKING MANUAL WORK WITH PAPER AND PENCIL, DRAWING OUT GRIDS OF DOTS AND CROSSES, HE FINALLY DISCOVERED A REPEATING PATTERN USING ROWS OF 41. HE CORRECTLY REALISED THIS WAS HOW MANY POSITIONS THE FIRST OF THE ENCODING WHEELS MUST HAVE IN THE UNKNOWN MACHINE. FROM THIS BREAK, WITH THE ASSISTANCE OF OTHER CODEBREAKERS, HE MANAGED TO SUCCESSFULLY RECREATE THE WORKINGS OF THE WHOLE MACHINE. REMEMBER, THIS WAS WITHOUT EVER SEEING THE LORENZ WHICH WAS AN ASTOUNDING PIECE OF WORK. BILL TUTTE, WHOSE CENTENARY WILL BE CELEBRATED IN MAY THIS YEAR, DID FURTHER WORK ON METHODS WHICH COULD POTENTIALLY BREAK INTO AN ENCODED MESSAGE, BUT IT INVOLVED A HUGE AMOUNT OF MANUAL EFFORT TO COUNT RESULTS FROM ALL SETTINGS UNTIL THE CORRECT ONE WAS FOUND. MAX NEWMAN MANAGED THE CONSTRUCTION OF A MACHINE TO USE TUTTES CALCULATIONS, WHICH WAS NICKNAMED HEATH ROBINSON, BUT IT WAS, UNFORTUNATELY, RELATIVELY SLOW AND UNRELIABLE. THEY INVITED, TOMMY FLOWERS, FROM THE POST OFFICE RESEARCH STATION IN DOLLIS HILL TO SEE IF HE COULD IMPROVE THE MACHINE. TOMMY FLOWERS CAME BACK TO THEM WITH A PLAN TO BUILD A NEW MACHINE USING 1500 THERMIONIC VALVES. VALVES AT THIS TIME WERE BELIEVED TO BE UNRELIABLE AND REQUIRE REGULAR REPLACEMENT, BUT TOMMY FLOWERS KNEW FROM HIS RESEARCH THAT IF NOT SWITCHED OFF, THEY WORKED PERFECTLY. WHILE BLETCHLEY PARK INITIALLY REFUSED, FLOWERS RETURNED TO DOLLIS HILL AND PERSUADED HIS SUPERIORS TO CONTINUE TO BUILD THIS MACHINE. IN JANUARY 1944, THE FIRST COLOSSUS WAS DELIVERED TO BLETCHLEY PARK, AND BY FEBRUARY WAS RUNNING SUCCESSFULLY AND RELIABLY FIRST TIME, MUCH TO EVERYONES ASTONISHMENT THEY QUICKLY PLACED ORDERS FOR AS MANY AS POSSIBLE, FLOWERS ALREADY HAVING STARTED WORKING ON A FASTER MARK 2. A FURTHER NINE COLOSSUS COMPUTERS WERE DELIVERED TO BLETCHLEY PARK BY THE END OF THE WAR (APPROXIMATELY ONE PER MONTH) AND THEY HELPED BREAK AN AMAZING 63 MILLION CHARACTERS, SHORTENING THE CONFLICT AND SAVING MANY LIVES. AFTER THE WAR, CHURCHILL ORDERED THE DISMANTLING OF ALL BUT TWO OF THE MACHINES AND THEIR EXISTENCE WAS KEPT SECRET FOR THIRTY YEARS. TONY SALE, AN ELECTRONIC ENGINEER WORKING AS SENIOR CURATOR AT THE SCIENCE MUSEUM, ALONG WITH SEVERAL COLLEAGUES STARTED, IN 1991, THE CAMPAIGN TO SAVE BLETCHLEY PARK FROM PROPERTY DEVELOPERS. HE ALSO BEGAN GATHERING INFORMATION ABOUT COLOSSUS. BY 1993, HE HAD RECOVERED EIGHT PHOTOGRAPHS FROM 1945, PLUS SOME FRAGMENTS OF CIRCUIT DIAGRAMS. HE STARTED TO BELIEVE THAT IT WOULD BE POSSIBLE TO REBUILD COLOSSUS, ALTHOUGH HE SAID THAT NOBODY BELIEVED THAT THIS WOULD BE POSSIBLE JUST LIKE TOMMY FLOWERS BEFORE HIM AFTER MONTHS OF WORK AND WITH HELP FROM THE ORIGINAL DESIGNER OF THE OPTICAL TAPE SYSTEM, DR ARNOLD LYNCH, HE MANAGED TO RE-ENGINEER THE BASIC SYSTEM. HE VISITED DR ALLEN COOMBS, WHO HELPED BUILD THE MK 2 COLOSSUS, ALONG WITH HARRY FENSON, ONE OF THE ORIGINAL COLOSSUS ENGINEERS. DR COOMBS GAVE TONY HIS WARTIME NOTES AND SOME CIRCUIT DIAGRAMS. USING HIS, AND HIS WIFE MARGARETS OWN FUNDS, HE STARTED THE HUGE TASK REBUILDING THE COLOSSUS. HE PUT TOGETHER A TEAM OF EX-POST OFFICE AND RADIO ENGINEERS TO HELP THE REBUILD. ON 6TH JUNE 1996, A BASIC WORKING COLOSSUS REBUILD WAS SWITCHED ON, AN OCCASION WHERE DR TOMMY FLOWERS ATTENDED AS WELL AS MANY PEOPLE WHO WORKED AT BLETCHLEY PARK DURING THE WAR. THE NEWMANRY REPORT WAS DECLASSIFIED IN 2000, ALLOWING THEM TO BUILD A WORKING COLOSSUS MK 2 BY 1ST JUNE 2004, THE 60TH ANNIVERSARY OF THE FIRST RUNNING OF A COLOSSUS MK 2 IN 1944. THE REBUILD CAN BE SEEN IN THE NATIONAL MUSEUM OF COMPUTING IN BLOCK H LOCATED WITHIN BLETCHLEY PARK. IT STANDS IN THE ORIGINAL ROOM WHERE COLOSSUS NO 9 STOOD IN WORLD WAR II. IT IS A MARVELLOUS WORKING TRIBUTE TO TOMMY FLOWERS AND THE ENGINEERS AT DOLLIS HILL, TO BILL TUTTE, JOHN TILTMAN, MAX NEWMAN, RALPH TESTER AND ALL THE CODE BREAKERS AT BLETCHLEY PARK, ALL THE WRNS WHO OPERATED COLOSSUS AND THE RADIO INTERCEPTORS AT KNOCKHOLT. BY MARTIN GILLOW, VIRTUALCOLOSSUS.CO.UK", + recipeConfig: [ + { + "op": "Lorenz", + "args": ["SZ42b", "ZMUG Pattern", true, "Receive", "Plaintext", "Plaintext", "5/8/9", 32, 28, 24, 11, 44, 6, 50, 34, 12, 18, 18, 9, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] + } + ] } + ]); From d5cfe9f262ca6bdd5dfc4f689bf8a8ee581e2fba Mon Sep 17 00:00:00 2001 From: VirtualColossus Date: Thu, 31 Oct 2019 13:54:52 +0000 Subject: [PATCH 17/17] removed duplicate test --- tests/operations/tests/Lorenz.mjs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/operations/tests/Lorenz.mjs b/tests/operations/tests/Lorenz.mjs index 52705f694..22bf82d95 100644 --- a/tests/operations/tests/Lorenz.mjs +++ b/tests/operations/tests/Lorenz.mjs @@ -79,18 +79,6 @@ TestRegister.addTests([ } ] }, - { - // KH Pattern, all 1s - name: "Lorenz SZ42a: KH pattern, plain text, all 1s", - input: "HELLO WORLD, THIS IS A TEST MESSAGE.", - expectedOutput: "VIC3TS/ZOHUYXWLTUXPV9ZNOTW9IXJPFDLIBB5ZD9K", - recipeConfig: [ - { - "op": "Lorenz", - "args": ["SZ42a", "KH Pattern", false, "Send", "Plaintext", "Plaintext", "5/8/9", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ".x...xx.x.x..xxx.x.x.xxxx.x.x.x.x.x..x.xx.x", ".xx.x.xxx..x.x.x..x.xx.x.xxx.x....x.xx.x.x.x..x", ".x.x.x..xxx....x.x.xx.x.x.x..xxx.x.x..x.x.xx..x.x.x", ".xx...xxxxx.x.x.xx...x.xx.x.x..x.x.xx.x..x.x.x.x.x.x.", "xx...xx.x..x.xx.x...x.x.x.x.x.x.x.x.xx..xxxx.x.x...xx.x..x.", "x.x.x.x.x.x...x.x.x...x.x.x...x.x....", ".xxxx.xxxx.xxx.xxxx.xx....xxx.xxxx.xxxx.xxxx.xxxx.xxx.xxxx...", ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..", "x..xxx...x.xxxx..xx..x..xx.xx..", "..xx..x.xxx...xx...xx..xx.xx.", "xx..x..xxxx..xx.xxx....x..", "xx..xx....xxxx.x..x.x.."] - } - ] - }, { // KH Pattern, Full Test on real message name: "Lorenz SZ42a: Receive, KH pattern, ITA2 output",