/// <summary> /// Encrypts or decrypts a string with the given key (rotor positions) /// Unknown symbols are ignored (=retuned unchanged) and case is preserved. /// </summary> /// <param name="rotor1Pos">Position of rotor 1 (fastest)</param> /// <param name="rotor2Pos">Position of rotor 2 (middle)</param> /// <param name="rotor3Pos">Position of rotor 3 (slowest)</param> /// <param name="rotor4Pos">Position of rotor 4 (extra rotor for M4)</param> /// <param name="input">The text for en/decryption. All letters which are not in the alphabet are returned unprocessed.</param> /// <returns>The encrypted/decrypted string</returns> public string Encrypt(int rotor1Pos, int rotor2Pos, int rotor3Pos, int rotor4Pos, string input) { if (!Stopwatch.IsHighResolution) { logMessage("No high resolution timer available. Time measurements will be inaccurate!", NotificationLevel.Warning); } // Start the stopwatch Stopwatch sw = Stopwatch.StartNew(); // set the current key, i.e. the rotor positions iCfg.Rotor1pos = rotor1Pos; iCfg.Rotor2pos = rotor2Pos; iCfg.Rotor3pos = rotor3Pos; iCfg.Rotor4pos = rotor4Pos; // now perform the enigma operation for each character char[] result = new char[input.Length]; for (int i = 0; i < input.Length; i++) { result[i] = enigmacrypt(input[i]); //update the status, if we are not in anylzing mode // this must be deactivated during analysis, since it takes a lot of time if (settings.Action == 0 && !pluginFacade.Presentation.IsVisible) { pluginFacade.ShowProgress(i, input.Length); } } // Stop the stopwatch sw.Stop(); // Print some info on the console, if not in analyzing mode. if (settings.Action == 0) { logMessage(String.Format("Enigma processing done! Processed {0} characters in {1} ms!", input.Length, sw.ElapsedMilliseconds), NotificationLevel.Info); } return(new string(result)); }
private const int maxAnalysisEntries = 10; // should go in settings under "Analysis Options" #endregion #region Private member methods /// <summary> /// This method basically brute-forces all possible rotors /// </summary> /// <param name="text">The ciphertext</param> private void analyzeRotors(string text) { // Start the stopwatch Stopwatch sw = Stopwatch.StartNew(); int trials = 0; for (int i = 0; i < 8; i++) { //Rotor 3 (slowest) if (!includeRotor(i)) { continue; } settings.Rotor3 = i; for (int j = 0; j < 8; j++) { // Rotor 2 (middle) if (!includeRotor(j) || j == i) { continue; } settings.Rotor2 = j; for (int k = 0; k < 8; k++) { // Rotor 1 (fastest) if (!includeRotor(k) || k == i || k == j) { continue; } settings.Rotor1 = k; //set the internal Config to the new rotors core.setInternalConfig(k, j, i, 0, settings.Reflector, settings.AnalyzeRings ? 1 : settings.Ring1, settings.AnalyzeRings ? 1 : settings.Ring2, settings.AnalyzeRings ? 1 : settings.Ring3, settings.Ring4, settings.AnalyzePlugs ? settings.Alphabet : settings.PlugBoard); analyzeKeys(text); trials++; pluginFacade.ShowProgress(i * Math.Pow(8, 2) + j * 8 + k, Math.Pow(8, 3)); if (stop) { break; } } // Rotor 1 if (stop) { break; } } // Rotor 2 if (stop) { break; } } // Rotor 3 // Stop the stopwatch sw.Stop(); string msg = String.Format("Processed {0} rotor permutations in {1}!", trials, sw.Elapsed.ToString()); pluginFacade.LogMessage(msg, NotificationLevel.Info); }