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

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

shortened license text to boilerplate notice in all source files

File size: 12.7 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 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 };
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, DisplayLevel.Beginner,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, DisplayLevel.Beginner,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, DisplayLevel.Beginner,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, DisplayLevel.Expert,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, DisplayLevel.Beginner, 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        /// <summary>
149        /// Vigenere decryption
150        /// </summary>
151        public void Decrypt()
152        {
153            ProcessVigenere(VigenereMode.decrypt);
154        }
155
156        #endregion
157
158        #region IPlugin members
159        public void Initialize()
160        {
161        }
162
163        public void Dispose()
164        {
165            foreach (CryptoolStream stream in listCryptoolStreamsOut)
166            {
167                stream.Close();
168            }
169            listCryptoolStreamsOut.Clear();
170        }
171
172        public bool HasChanges
173        {
174            get { return settings.HasChanges; }
175            set { settings.HasChanges = value; }
176        }
177
178        /// <summary>
179        /// Fire if progress bar status was changed
180        /// </summary>
181        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
182
183        /// <summary>
184        /// Fire if a new message has to be shown in the status bar
185        /// </summary>
186        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
187
188        public System.Windows.Controls.UserControl Presentation
189        {
190            get { return null; }
191        }
192
193        public System.Windows.Controls.UserControl QuickWatchPresentation
194        {
195            get { return null; }
196        }
197
198        public void Stop()
199        {
200        }
201
202        public void PostExecution()
203        {
204            Dispose();
205        }
206
207        public void PreExecution()
208        {
209            Dispose();
210        }
211
212        #endregion
213
214        #region INotifyPropertyChanged Members
215
216        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
217
218        public void OnPropertyChanged(string name)
219        {
220            if (PropertyChanged != null)
221            {
222                PropertyChanged(this, new PropertyChangedEventArgs(name));
223            }
224        }
225
226        #endregion
227
228
229
230        #region Private methods
231
232        /// <summary>
233        /// Does the actual Vigenere processing, i.e. encryption or decryption
234        /// </summary>
235        /// <param name="mode"></param>
236        private void ProcessVigenere(VigenereMode mode)
237        {
238            VigenereSettings cfg = (VigenereSettings)this.settings;
239            StringBuilder output = new StringBuilder(String.Empty);
240            string alphabet = cfg.AlphabetSymbols;
241
242            if (!cfg.CaseSensitiveAlphabet)
243            {
244                alphabet = cfg.AlphabetSymbols.ToUpper();
245            }
246            if (inputString != null)
247            {
248                int shiftPos = 0;
249                for (int i = 0; i < inputString.Length; i++)
250                {
251                    //get plaintext char which is currently processed
252                    char currentChar = inputString[i];
253
254                    //remember if it is upper case (ohterwise lowercase is assumed)
255                    bool uppercase = char.IsUpper(currentChar);
256                   
257                    //get the position of the plaintext character in the alphabet
258                    int ppos = 0;
259                    if (cfg.CaseSensitiveAlphabet)
260                    {
261                        ppos = alphabet.IndexOf(currentChar);
262                    }
263                    else
264                    {
265                        ppos = alphabet.IndexOf(char.ToUpper(currentChar));
266                    }
267
268                    if (ppos >= 0)
269                    {
270                        //found the plaintext character in the alphabet, begin shifting
271                        int cpos = 0;
272                        switch (mode)
273                        {
274                            case VigenereMode.encrypt:
275                                cpos = (ppos + cfg.ShiftKey[shiftPos]) % alphabet.Length;
276                                break;
277                            case VigenereMode.decrypt:
278                                cpos = (ppos - cfg.ShiftKey[shiftPos] + alphabet.Length) % alphabet.Length;
279                                break;
280                        }
281
282                        //inkrement shiftPos to map inputString whith all keys
283                        //if shiftPos > ShiftKey.Length, begin again at the beginning
284                        shiftPos++;
285                        if (shiftPos >= cfg.ShiftKey.Length)
286                            shiftPos = 0;
287
288                        //we have the position of the ciphertext character, now we have to output it in the right case
289                        if (cfg.CaseSensitiveAlphabet)
290                        {
291                            output.Append(alphabet[cpos]);
292                        }
293                        else
294                        {
295                            if (uppercase)
296                            {
297                                output.Append(char.ToUpper(alphabet[cpos]));
298                            }
299                            else
300                            {
301                                output.Append(char.ToLower(alphabet[cpos]));
302                            }
303                        }
304                    }
305                    else
306                    {
307                        //the plaintext character was not found in the alphabet, begin handling with unknown characters
308                        switch ((VigenereSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
309                        {
310                            case VigenereSettings.UnknownSymbolHandlingMode.Ignore:
311                                output.Append(inputString[i]);
312                                break;
313                            case VigenereSettings.UnknownSymbolHandlingMode.Replace:
314                                output.Append('?');
315                                break;
316                        }
317                    }
318
319                    //show the progress
320                    if (OnPluginProgressChanged != null)
321                    {
322                        OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
323                    }
324                }
325                outputString = output.ToString();
326                OnPropertyChanged("OutputString");
327                OnPropertyChanged("OutputData");
328            }
329        }
330
331        /// <summary>
332        /// Handles log messages from the settings class
333        /// </summary>
334        /// <param name="sender"></param>
335        /// <param name="msg"></param>
336        /// <param name="logeLevel"></param>
337        private void Vigenere_LogMessage(string msg, NotificationLevel logLevel)
338        {
339            if (OnGuiLogNotificationOccured != null)
340            {
341                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(msg, this, logLevel));
342            }
343        }
344
345        #endregion
346
347        #region IPlugin Members
348
349#pragma warning disable 67
350                                public event StatusChangedEventHandler OnPluginStatusChanged;
351#pragma warning restore
352
353        public void Execute()
354        {
355            switch (settings.Action)
356            {
357                case 0:
358                    Encrypt();
359                    break;
360                case 1:
361                    Decrypt();
362                    break;
363                default:
364                    break;
365            }
366        }
367
368        public void Pause()
369        {
370
371        }
372
373        #endregion
374
375    }
376}
Note: See TracBrowser for help on using the repository browser.