source: trunk/CrypPlugins/Vigenere/Vigenere.cs @ 2334

Last change on this file since 2334 was 2334, checked in by Matthäus Wander, 11 years ago

removed 1006 occurences of DisplayLevel in 218 files (see #122)

File size: 17.1 KB
Line 
1/*
2   Copyright 2008 Sebastian Przybylski, University of Siegen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Collections.Generic;
19using System.Linq;
20using System.Text;
21using Cryptool.PluginBase;
22using System.IO;
23using System.ComponentModel;
24using Cryptool.PluginBase.Cryptography;
25using Cryptool.PluginBase.IO;
26
27namespace Cryptool.Vigenere
28{
29    [Author("Sebastian Przybylski", "sebastian@przybylski.org", "Uni-Siegen", "http://www.uni-siegen.de")]
30    [PluginInfo(false, "VigenÚre", "VigenÚre -- classic or autokey polyalphabetic substitution cipher", "Vigenere/DetailedDescription/Description.xaml",
31      "Vigenere/Images/icon.png", "Vigenere/Images/encrypt.png", "Vigenere/Images/decrypt.png")]
32    [EncryptionType(EncryptionType.Classic)]
33    public class Vigenere : IEncryption
34    {
35        #region Private variables
36
37        private VigenereSettings settings;
38        private CryptoolStream outputData;
39        private string inputString;
40        private string outputString;
41        private char[] keyword;
42        private enum VigenereMode { encrypt, decrypt, autoencrypt, autodecrypt };
43        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
44
45        #endregion
46
47        #region Public interface
48
49        /// <summary>
50        /// Constructor
51        /// </summary>
52        public Vigenere()
53        {
54            this.settings = new VigenereSettings();
55            ((VigenereSettings)(this.settings)).LogMessage += Vigenere_LogMessage;
56        }
57
58        /// <summary>
59        /// Get or set all settings for this algorithm
60        /// </summary>
61        public ISettings Settings
62        {
63            get { return this.settings; }
64            set { this.settings = (VigenereSettings)value; }
65        }
66
67        [PropertyInfo(Direction.OutputData, "Stream output", "The string after processing with the VigenÚre cipher is converted to a stream.Default encoding is used.", null, false, false,QuickWatchFormat.Text, null)]
68        public CryptoolStream OutputData
69        {
70            get
71            {
72                if (outputString != null)
73                {
74                    CryptoolStream cs = new CryptoolStream();
75                    listCryptoolStreamsOut.Add(cs);
76                    cs.OpenRead(this.GetPluginInfoAttribute().Caption, Encoding.Default.GetBytes(outputString.ToCharArray()));
77                    return cs;
78                }
79                else
80                {
81                    return null;
82                }
83            }
84            set { }
85        }
86
87        [PropertyInfo(Direction.InputData, "Text input", "Input a string to be processed by the VigenÚre cipher", null, true, false,QuickWatchFormat.Text, null)]
88        public string InputString
89        {
90            get { return this.inputString; }
91            set
92            {
93                if (value != inputString)
94                {
95                    this.inputString = value;
96                    OnPropertyChanged("InputString");
97                }
98            }
99        }
100
101        [PropertyInfo(Direction.OutputData,"Text output", "The string after processing with the VigenÚre cipher", null, false, false,QuickWatchFormat.Text, null)]
102        public string OutputString
103        {
104            get { return this.outputString; }
105            set
106            {
107                outputString = value;
108                OnPropertyChanged("OutputString");
109            }
110        }
111
112        [PropertyInfo(Direction.InputData, "External alphabet input", "Input a string containing the alhabet which should be used by VigenÚre. If no alphabet is provided on this input, the internal alphabet will be used.", null, false, false,QuickWatchFormat.Text, null)]
113        public string InputAlphabet
114        {
115            get { return ((VigenereSettings)this.settings).AlphabetSymbols; }
116            set
117            {
118                if (value != null && value != settings.AlphabetSymbols) 
119                { 
120                    ((VigenereSettings)this.settings).AlphabetSymbols = value;
121                    OnPropertyChanged("InputAlphabet");
122                }
123            }
124        }
125        [PropertyInfo(Direction.InputData, "String", "Keyword as derived by the VigenereAnalyser", "", false, false, QuickWatchFormat.Text, null)]
126        public string ShiftValue
127        {
128            get { return settings.ShiftChar; }
129            set
130            {
131                if (value != settings.ShiftChar)
132                {
133                    settings.ShiftChar=value;
134                    OnPropertyChanged("ShiftValue");
135
136                }
137            }
138        }
139
140        /// <summary>
141        /// Vigenere encryption
142        /// </summary>
143        public void Encrypt()
144        {
145            ProcessVigenere(VigenereMode.encrypt);
146        }
147
148        public void AutoKeyEncrypt()
149        {
150            ProcessVigenere(VigenereMode.autoencrypt);
151        }
152
153        /// <summary>
154        /// Vigenere decryption
155        /// </summary>
156        public void Decrypt()
157        {
158            ProcessVigenere(VigenereMode.decrypt);
159        }
160
161        public void AutoKeyDecrypt()
162        {
163            ProcessVigenere(VigenereMode.autodecrypt);
164        }
165
166        #endregion
167
168        #region IPlugin members
169        public void Initialize()
170        {
171        }
172
173        public void Dispose()
174        {
175            foreach (CryptoolStream stream in listCryptoolStreamsOut)
176            {
177                stream.Close();
178            }
179            listCryptoolStreamsOut.Clear();
180        }
181
182        public bool HasChanges
183        {
184            get { return settings.HasChanges; }
185            set { settings.HasChanges = value; }
186        }
187
188        /// <summary>
189        /// Fire if progress bar status was changed
190        /// </summary>
191        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
192
193        /// <summary>
194        /// Fire if a new message has to be shown in the status bar
195        /// </summary>
196        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
197
198        public System.Windows.Controls.UserControl Presentation
199        {
200            get { return null; }
201        }
202
203        public System.Windows.Controls.UserControl QuickWatchPresentation
204        {
205            get { return null; }
206        }
207
208        public void Stop()
209        {
210        }
211
212        public void PostExecution()
213        {
214            Dispose();
215        }
216
217        public void PreExecution()
218        {
219            Dispose();
220        }
221
222        #endregion
223
224        #region INotifyPropertyChanged Members
225
226        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
227
228        public void OnPropertyChanged(string name)
229        {
230            if (PropertyChanged != null)
231            {
232                PropertyChanged(this, new PropertyChangedEventArgs(name));
233            }
234        }
235
236        #endregion
237
238
239
240        #region Private methods
241
242        /// <summary>
243        /// Does the actual Vigenere processing, i.e. encryption or decryption
244        /// </summary>
245        /// <param name="mode"></param>
246        private void ProcessVigenere(VigenereMode mode)
247        {
248            VigenereSettings cfg = (VigenereSettings)this.settings;
249            StringBuilder output = new StringBuilder(String.Empty);
250            string alphabet = cfg.AlphabetSymbols;
251            int autopos = 0;
252
253            if (!cfg.CaseSensitiveAlphabet)
254            {
255                alphabet = cfg.AlphabetSymbols.ToUpper();
256            }
257            if (inputString != null)
258            {
259                int shiftPos = 0;
260                for (int i = 0; i < inputString.Length; i++)
261                {
262                    //get plaintext char which is currently processed
263                    char currentChar = inputString[i];
264
265                    //remember if it is upper case (ohterwise lowercase is assumed)
266                    bool uppercase = char.IsUpper(currentChar);
267                   
268                    //get the position of the plaintext character in the alphabet
269                    int ppos = 0;
270                    if (cfg.CaseSensitiveAlphabet)
271                    {
272                        ppos = alphabet.IndexOf(currentChar);
273                    }
274                    else
275                    {
276                        ppos = alphabet.IndexOf(char.ToUpper(currentChar));
277                    }
278
279                    if (ppos >= 0)
280                    {
281
282                        //found the plaintext character in the alphabet, begin shifting
283                        int cpos = 0;
284                        switch (mode)
285                        {
286                            case VigenereMode.encrypt:
287
288                                cpos = (ppos + cfg.ShiftKey[shiftPos]) % alphabet.Length;
289
290                                //inkrement shiftPos to map inputString whith all keys
291                                //if shiftPos > ShiftKey.Length, begin again at the beginning
292                                shiftPos++;
293                                if (shiftPos >= cfg.ShiftKey.Length) shiftPos = 0;
294                                break;
295                           
296                            case VigenereMode.decrypt:
297
298                                cpos = (ppos - cfg.ShiftKey[shiftPos] + alphabet.Length) % alphabet.Length;
299                               
300                                //inkrement shiftPos to map inputString whith all keys
301                                //if shiftPos > ShiftKey.Length, begin again at the beginning
302                                shiftPos++;
303                                if (shiftPos >= cfg.ShiftKey.Length) shiftPos = 0;
304                                break;
305
306                            case VigenereMode.autoencrypt:
307
308                                //key still used
309                                if (shiftPos < cfg.ShiftKey.Length)
310                                {
311                                    cpos = (ppos + cfg.ShiftKey[shiftPos]) % alphabet.Length;
312                                    shiftPos++;
313                                }
314                                else //using plaintext
315                                {
316                                    //taking the plaintextchar from the next position
317                                    int pkey = alphabet.IndexOf(char.ToUpper(inputString[autopos]));
318                                    //check if the next plaintextchar is in the alphabet
319                                    while (pkey < 0)
320                                    {
321                                        autopos++;
322                                        pkey = alphabet.IndexOf(char.ToUpper(inputString[autopos]));
323                                    }
324
325                                    cpos = (ppos + pkey) % alphabet.Length;
326                                    autopos++;
327                                }
328                                break;
329
330
331                            case VigenereMode.autodecrypt:
332
333                                //key still used
334                                if (shiftPos < cfg.ShiftKey.Length)
335                                {
336                                    cpos = (ppos - cfg.ShiftKey[shiftPos] + alphabet.Length) % alphabet.Length;
337                                    shiftPos++;
338                                }
339                                else //using plaintext
340                                {
341                                    outputString = output.ToString();
342
343                                    //taking the deciphered plaintextchar from the next position
344                                    int pkey = alphabet.IndexOf(char.ToUpper(outputString[autopos]));
345                                    //check if the next deciphered plaintextchar is in the alphabet
346                                    while (pkey < 0)
347                                    {
348                                        autopos++;
349                                        try
350                                        {
351                                            pkey = alphabet.IndexOf(char.ToUpper(outputString[autopos]));
352                                        }
353                                        catch
354                                        {
355                                            //there is an internal failure that doesn't make sense
356                                            //supposly it has something to do with the threads -.-'/
357                                        }
358                                    }
359
360                                    cpos = (ppos - pkey + alphabet.Length) % alphabet.Length;
361                                    autopos++;
362                                }
363                                break;
364                        }
365
366                                                 
367                        //we have the position of the ciphertext character, now we have to output it in the right case
368                        if (cfg.CaseSensitiveAlphabet)
369                        {
370                            output.Append(alphabet[cpos]);
371                        }
372                        else
373                        {
374                            if (uppercase)
375                            {
376                                output.Append(char.ToUpper(alphabet[cpos]));
377                            }
378                            else
379                            {
380                                output.Append(char.ToLower(alphabet[cpos]));
381                            }
382                        }
383                    }
384                    else
385                    {
386                        //the plaintext character was not found in the alphabet, begin handling with unknown characters
387                        switch ((VigenereSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
388                        {
389                            case VigenereSettings.UnknownSymbolHandlingMode.Ignore:
390                                output.Append(inputString[i]);
391                                break;
392                            case VigenereSettings.UnknownSymbolHandlingMode.Replace:
393                                output.Append('?');
394                                break;
395                        }
396                    }
397
398                    //show the progress
399                    if (OnPluginProgressChanged != null)
400                    {
401                        OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
402                    }
403                }
404                outputString = output.ToString();
405                OnPropertyChanged("OutputString");
406                OnPropertyChanged("OutputData");
407            }
408        }
409
410        /// <summary>
411        /// Handles log messages from the settings class
412        /// </summary>
413        /// <param name="sender"></param>
414        /// <param name="msg"></param>
415        /// <param name="logeLevel"></param>
416        private void Vigenere_LogMessage(string msg, NotificationLevel logLevel)
417        {
418            if (OnGuiLogNotificationOccured != null)
419            {
420                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(msg, this, logLevel));
421            }
422        }
423
424        #endregion
425
426        #region IPlugin Members
427
428#pragma warning disable 67
429                                public event StatusChangedEventHandler OnPluginStatusChanged;
430#pragma warning restore
431
432        public void Execute()
433        {
434           switch (settings.Modus)
435           {
436               //Classic Modus
437               case 0:
438
439                    switch (settings.Action)
440                    {
441                        case 0:
442                            Encrypt();
443                            break;
444                        case 1:
445                            Decrypt();
446                            break;
447                        default:
448                            break;
449                    }
450                    break;
451
452               //Autokey Modus
453               case 1:
454
455                    switch (settings.Action)
456                    {
457                        case 0:
458                            AutoKeyEncrypt();
459                            break;
460                        case 1:
461                            AutoKeyDecrypt();
462                            break;
463                        default:
464                            break;
465                    }
466                    break;
467       
468            }
469       
470        }
471
472        public void Pause()
473        {
474
475        }
476
477        #endregion
478
479    }
480}
Note: See TracBrowser for help on using the repository browser.