/// <summary> /// Constructor /// </summary> public Vigenere() { this.settings = new VigenereSettings(); this.settings.LogMessage += Vigenere_LogMessage; }
/// <summary> /// Does the actual Vigenere processing, i.e. encryption or decryption /// </summary> /// <param name="mode"></param> private void ProcessVigenere(VigenereMode mode) { VigenereSettings cfg = (VigenereSettings)this.settings; StringBuilder output = new StringBuilder(String.Empty); string alphabet = cfg.AlphabetSymbols; int autopos = 0; if (!cfg.CaseSensitiveAlphabet) { alphabet = cfg.AlphabetSymbols.ToUpper(); } if (inputString != null) { int shiftPos = 0; for (int i = 0; i < inputString.Length; i++) { //get plaintext char which is currently processed char currentChar = inputString[i]; //remember if it is upper case (ohterwise lowercase is assumed) bool uppercase = char.IsUpper(currentChar); //get the position of the plaintext character in the alphabet int ppos = 0; if (cfg.CaseSensitiveAlphabet) { ppos = alphabet.IndexOf(currentChar); } else { ppos = alphabet.IndexOf(char.ToUpper(currentChar)); } if (ppos >= 0) { //found the plaintext character in the alphabet, begin shifting int cpos = 0; switch (mode) { case VigenereMode.encrypt: cpos = (ppos + cfg.ShiftKey[shiftPos]) % alphabet.Length; //inkrement shiftPos to map inputString whith all keys //if shiftPos > ShiftKey.Length, begin again at the beginning shiftPos++; if (shiftPos >= cfg.ShiftKey.Length) { shiftPos = 0; } break; case VigenereMode.decrypt: cpos = (ppos - cfg.ShiftKey[shiftPos] + alphabet.Length) % alphabet.Length; //inkrement shiftPos to map inputString whith all keys //if shiftPos > ShiftKey.Length, begin again at the beginning shiftPos++; if (shiftPos >= cfg.ShiftKey.Length) { shiftPos = 0; } break; case VigenereMode.autoencrypt: //key still used if (shiftPos < cfg.ShiftKey.Length) { cpos = (ppos + cfg.ShiftKey[shiftPos]) % alphabet.Length; shiftPos++; } else //using plaintext { //taking the plaintextchar from the next position int pkey = alphabet.IndexOf(char.ToUpper(inputString[autopos])); //check if the next plaintextchar is in the alphabet while (pkey < 0) { autopos++; pkey = alphabet.IndexOf(char.ToUpper(inputString[autopos])); } cpos = (ppos + pkey) % alphabet.Length; autopos++; } break; case VigenereMode.autodecrypt: //key still used if (shiftPos < cfg.ShiftKey.Length) { cpos = (ppos - cfg.ShiftKey[shiftPos] + alphabet.Length) % alphabet.Length; shiftPos++; } else //using plaintext { outputString = output.ToString(); //taking the deciphered plaintextchar from the next position int pkey = alphabet.IndexOf(char.ToUpper(outputString[autopos])); //check if the next deciphered plaintextchar is in the alphabet while (pkey < 0) { autopos++; try { pkey = alphabet.IndexOf(char.ToUpper(outputString[autopos])); } catch { //there is an internal failure that doesn't make sense //supposly it has something to do with the threads -.-'/ } } cpos = (ppos - pkey + alphabet.Length) % alphabet.Length; autopos++; } break; } //we have the position of the ciphertext character, now we have to output it in the right case if (cfg.CaseSensitiveAlphabet) { output.Append(alphabet[cpos]); } else { if (uppercase) { output.Append(char.ToUpper(alphabet[cpos])); } else { output.Append(char.ToLower(alphabet[cpos])); } } } else { //the plaintext character was not found in the alphabet, begin handling with unknown characters switch ((VigenereSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling) { case VigenereSettings.UnknownSymbolHandlingMode.Ignore: output.Append(inputString[i]); break; case VigenereSettings.UnknownSymbolHandlingMode.Replace: output.Append('?'); break; } } //show the progress Progress(i, inputString.Length - 1); } outputString = settings.AlphabetCase | settings.MemorizeCase ? output.ToString() : output.ToString().ToUpper(); OnPropertyChanged("OutputString"); } }