UNPKG

enigma

Version:

Implementation of an enigma machine

359 lines (254 loc) 9.62 kB
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.enigma=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ var Enigma = require('./lib/enigma'); var Rotor = require('./lib/rotor'); var Umkehrwalze = require('./lib/umkehrwalze'); var Eintrittswalze = require('./lib/eintrittswalze'); var Steckerbrett = require('./lib/steckerbrett'); module.exports = { Enigma: Enigma, Rotor: Rotor, Umkehrwalze: Umkehrwalze, Reflector: Umkehrwalze, Eintrittswalze: Eintrittswalze, EntryWheel: Eintrittswalze, Steckerbrett: Steckerbrett, Plugboard: Steckerbrett }; },{"./lib/eintrittswalze":2,"./lib/enigma":3,"./lib/rotor":4,"./lib/steckerbrett":5,"./lib/umkehrwalze":6}],2:[function(require,module,exports){ var Walze = require('./walze'); module.exports = Eintrittswalze; function Eintrittswalze(wiring, name) { this.setWiring(wiring); this.setName(name); return this; } Eintrittswalze.prototype = new Walze(); },{"./walze":7}],3:[function(require,module,exports){ module.exports = Enigma; function Enigma(rotors, ukw, steckerbrett, etw) { this.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); if ( (rotors.length < 3 || rotors.length > 4) || typeof ukw === 'undefined' || typeof steckerbrett === 'undefined' || typeof etw === 'undefined') { throw new Error('Only three or four rotors are supported, and reflector, plugboard and entry wheel must be set'); } this.rotors = rotors; this.ukw = ukw; this.steckerbrett = steckerbrett; this.etw = etw; return this; } Enigma.prototype.signal = function(signal) { // Rotate by 1 step this.rotate(); // Send signal through the Steckerbrett signal = this.steckerbrett.signal(signal); // Send signal through the Eintrittswalze signal = this.etw.signal(signal); // Send signal through every rotor for (var i = this.rotors.length - 1; i >= 0; i--) { signal = this.rotors[i].signal(signal); } // Send signal through the Umkehrwalze signal = this.ukw.signal(signal); // Send signal through every rotor in reverse direction for (var j = 0; j < this.rotors.length; j++) { signal = this.rotors[j].signal(signal, true); } // Send signal through the Eintrittswalze in reverse direction signal = this.etw.signal(signal, true); // Send signal through the Steckerbrett in reverse direction signal = this.steckerbrett.signal(signal, true); return signal; }; Enigma.prototype.rotate = function() { var notched = []; var turned = []; for (var i = 0; i < this.rotors.length; i++) { turned[i] = false; notched.push( this.rotors[i].inNotch() ); } for (var j = this.rotors.length - 1; j >= 0; j--) { if ( (j === this.rotors.length - 1) || ( turned[j+1] && notched[j+1] ) || ( turned[j+1] && notched[j] && j > 0 ) ) { this.rotors[j].rotate(); turned[j] = true; } } }; Enigma.prototype.string = function(string) { // Convert argument to string, upper case, and remove illegal letters (such as spaces) string = typeof string === 'string' ? string : string.toString(); string = string.toUpperCase().replace(new RegExp('[^' + this.etw.wiring + ']','g'), '').split(''); var res = ''; for (var i = 0; i < string.length; i++) { res += this.signal(string[i]); } return res; }; Enigma.prototype.getPositions = function(){ var str = ''; for (var i = 0; i < this.rotors.length; i++) { str += this.rotors[i].getPosition(); } return str; }; Enigma.prototype.setPositions = function(positions) { positions = positions.split(''); for (var i = 0; i < this.rotors.length; i++) { this.rotors[i].setPosition(positions[i]); } }; Enigma.prototype.getRingSettings = function() { var str = ''; for (var i = 0; i < this.rotors.length; i++) { str += this.rotors[i].getRingSetting(); } return str; }; Enigma.prototype.setRingSettings = function(settings) { settings = settings.split(''); for (var i = 0; i < this.rotors.length; i++) { this.rotors[i].setRingSetting(settings[i]); } }; },{}],4:[function(require,module,exports){ var Walze = require('./walze'); module.exports = Rotor; function Rotor(wiring, notches, name) { this.position = 0; // Enigmas start with 01 this.ringsetting = 0; // ring setting - Ringstellung this.setWiring(wiring); this.setNotches(notches); this.setName(name); return this; } Rotor.prototype = new Walze(); Rotor.prototype.signal = function(signal, reverse) { var pos; pos = this.alphabet.indexOf(signal); pos = ( pos + this.position + (this.alphabet.length) - this.ringsetting) % (this.alphabet.length); signal = this.alphabet[pos]; if ( reverse ) pos = this.wiring.indexOf(signal); signal = reverse ? this.alphabet[pos] : this.wiring[pos]; pos = this.alphabet.indexOf(signal); pos = ( pos + ( (this.alphabet.length) - this.position + this.ringsetting ) ) % (this.alphabet.length); signal = this.alphabet[pos]; return signal; }; Rotor.prototype.rotate = function() { this.position = (this.position + 1) % (this.alphabet.length); }; Rotor.prototype.inNotch = function() { var inNotch = false; for (var i = 0; i < this.notches.length; i++) { if( this.position === this.alphabet.indexOf(this.notches[i]) ) { inNotch = true; break; } } return inNotch; }; Rotor.prototype.setNotches = function(notches) { if ( typeof notches === 'string' ) { notches = notches.toUpperCase().split(''); } else if ( typeof notches === 'object' && notches instanceof Array ) { notches = notches.map(function(e) { return e.toString().toUpperCase(); }); } else { notches = []; } if ( notches.some( function(e,i,l){ return l.indexOf(e) !== l.lastIndexOf(e);} ) ) { throw new Error('notches has to consist of unique characters'); } if ( notches.length > this.alphabet.length ) { throw new Error('you can’t have more notches than characters on the rotor'); } this.notches = notches; }; Rotor.prototype.getPosition = function() { return this.alphabet[this.position]; }; Rotor.prototype.setPosition = function(position) { this.position = this.alphabet.indexOf(position); }; Rotor.prototype.getRingSetting = function() { return this.alphabet[this.ringsetting]; }; Rotor.prototype.setRingSetting = function(setting) { this.ringsetting = this.alphabet.indexOf(setting); }; },{"./walze":7}],5:[function(require,module,exports){ var Walze = require('./walze'); module.exports = Steckerbrett; function Steckerbrett(plugs, name) { this.setName(name); this.setPlugs(plugs); return this; } Steckerbrett.prototype = new Walze(); Steckerbrett.prototype.setPlugs = function(plugs) { if ( typeof plugs === 'string' ) { plugs = plugs.toUpperCase().split(' '); } else if ( typeof plugs === 'object' && plugs instanceof Array ) { plugs = plugs.map(function(e) { return e.toString().toUpperCase(); }); } else { plugs = []; } var wiring = this.alphabet.slice(); for (var i = 0; i < plugs.length; i++) { var plug = plugs[i].split(''); wiring[ this.alphabet.indexOf(plug[0]) ] = plug[1]; wiring[ this.alphabet.indexOf(plug[1]) ] = plug[0]; } if ( wiring.length > this.alphabet.length || plugs.length > Math.floor( this.alphabet.length/2 ) ) { throw new Error('The Steckerbrett only allows for ' + Math.floor( this.alphabet.length/2 ) + ' connections to be set'); } this.setWiring(wiring); }; },{"./walze":7}],6:[function(require,module,exports){ var Walze = require('./walze'); module.exports = Umkehrwalze; function Umkehrwalze(wiring, name) { this.setWiring(wiring); this.setName(name); return this; } Umkehrwalze.prototype = new Walze(); },{"./walze":7}],7:[function(require,module,exports){ module.exports = Walze; function Walze(wiring, name) { this.setWiring(wiring); this.setName(name); return this; } Walze.prototype.alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); Walze.prototype.setWiring = function(wiring) { if ( typeof wiring === 'string' ) { wiring = wiring.toUpperCase().split(''); } else if ( typeof wiring === 'object' && wiring instanceof Array ) { wiring = wiring.map(function(e) { return e.toString().toUpperCase(); }); } else { wiring = this.alphabet.slice(); } if ( wiring.some(function(e,i,l){ return l.indexOf(e) !== l.lastIndexOf(e);}) || wiring.length !== this.alphabet.length ) { throw new Error('The Walze must have ' + (this.alphabet.length) + ' unique characters.'); } this.wiring = wiring; }; Walze.prototype.setName = function(name) { if ( 'string' === typeof name) { this.name = name; } else { this.name = ''; } }; Walze.prototype.signal = function(signal, reverse) { var pos = reverse ? this.wiring.indexOf(signal) : this.alphabet.indexOf(signal); signal = reverse ? this.alphabet[pos] : this.wiring[pos]; return signal; }; },{}]},{},[1])(1) });