source: trunk/CrypPlugins/Caesar/Caesar.cs @ 1709

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

Caesar:

  • changeable settings during execution, closes #88
File size: 12.9 KB
Line 
1/*                             
2   Copyright 2009 Arno Wacker, Uni Duisburg-Essen
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.Collections.Generic;
18using System.Text;
19using Cryptool.PluginBase;
20using Cryptool.PluginBase.Cryptography;
21
22using System.ComponentModel;
23using Cryptool.PluginBase.IO;
24using System.Windows.Controls;
25using Cryptool.PluginBase.Miscellaneous;
26
27namespace Cryptool.Caesar
28{
29    [Author("Dr. Arno Wacker", "arno.wacker@cryptool.org", "Uni Duisburg-Essen", "http://www.vs.uni-duisburg-essen.de")]
30    [PluginInfo("Cryptool.Caesar.Resources.res", false, "pluginName", "pluginToolTip", "Caesar/DetailedDescription/Description.xaml",
31      "Caesar/Images/Caesar.png", "Caesar/Images/encrypt.png", "Caesar/Images/decrypt.png")] 
32    [EncryptionType(EncryptionType.Classic)]
33    public class Caesar : IEncryption
34    {
35        #region Private variables
36
37        private CaesarSettings settings;
38        // private CryptoolStream outputData;
39        private string inputString;
40        private string outputString;
41        private enum CaesarMode { encrypt, decrypt };
42        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
43        private bool isPlayMode = false;
44        #endregion
45       
46        #region Public interface
47
48        /// <summary>
49        /// Constructor
50        /// </summary>
51        public Caesar()
52        {
53            this.settings = new CaesarSettings();
54            this.settings.LogMessage += Caesar_LogMessage;
55            this.settings.ReExecute += Caesar_ReExecute;
56        }
57 
58        /// <summary>
59        /// Get or set all settings for this algorithm.
60        /// </summary>
61        public ISettings Settings
62        {
63            get { return (ISettings)this.settings; }
64            set { this.settings = (CaesarSettings)value; }
65        }
66
67
68        [PropertyInfo(Direction.OutputData, "propStreamOutputToolTip", "propStreamOutputDescription", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
69        public CryptoolStream OutputData
70        {
71            get
72            {
73                if (outputString != null)
74                {                   
75                    CryptoolStream cs = new CryptoolStream();
76                    listCryptoolStreamsOut.Add(cs);
77                    cs.OpenRead(Encoding.Default.GetBytes(outputString.ToCharArray()));
78                    return cs;
79                }
80                else
81                {
82                    return null;
83                }
84            }
85            set { }
86        }
87
88
89        [PropertyInfo(Direction.InputData, "Text input", "Input a string to be processed by the Caesar cipher", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
90        public string InputString
91        {
92            get { return this.inputString; }
93            set 
94            {
95              if (value != inputString)
96              {
97                this.inputString = value;
98                OnPropertyChanged("InputString");
99              }
100            }
101        }
102
103        [PropertyInfo(Direction.OutputData, "Text output", "The string after processing with the Caesar cipher", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
104        public string OutputString
105        {
106            get { return this.outputString; }
107            set
108            {
109                outputString = value;
110                OnPropertyChanged("OutputString");
111            }
112        }
113
114
115        [PropertyInfo(Direction.InputData, "External alphabet input", "Input a string containing the alphabet which should be used by Caesar.\nIf no alphabet is provided on this input, the internal alphabet will be used.", "", false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
116        public string InputAlphabet
117        {
118            get { return ((CaesarSettings)this.settings).AlphabetSymbols; }
119            set 
120            {
121              if (value != null && value != settings.AlphabetSymbols) 
122              { 
123                ((CaesarSettings)this.settings).AlphabetSymbols = value;
124                OnPropertyChanged("InputAlphabet");
125              } 
126            }
127        }
128
129        [PropertyInfo(Direction.InputData, "Shift value (integer)", "Same setting as Shift value in Settings-Pane but as dynamic input.", "", false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
130        public int ShiftKey
131        {
132          get { return settings.ShiftKey; }
133          set 
134          { 
135            if (value != settings.ShiftKey)
136            {
137              settings.ShiftKey = value;
138              // Execute();
139            }
140          }
141        }
142
143
144        /// <summary>
145        /// Caesar encryption
146        /// </summary>
147        public void Encrypt()
148        {
149            ProcessCaesar(CaesarMode.encrypt);
150        }
151
152        /// <summary>
153        /// Caesar decryption
154        /// </summary>
155        public void Decrypt()
156        {
157            ProcessCaesar(CaesarMode.decrypt);
158        }
159       
160        #endregion
161
162        #region IPlugin members
163        public void Initialize()
164        {
165
166        }
167
168        public void Dispose()
169        {
170          foreach (CryptoolStream stream in listCryptoolStreamsOut)
171          {
172            stream.Close();
173          }
174          listCryptoolStreamsOut.Clear();
175        }
176
177        public bool HasChanges
178        {
179          get { return settings.HasChanges; }
180          set { settings.HasChanges = value; }
181        }
182
183        /// <summary>
184        /// Feuern, wenn sich sich eine Änderung des Fortschrittsbalkens ergibt
185        /// </summary>
186        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
187
188        /// <summary>
189        /// Feuern, wenn ein neuer Text im Statusbar angezeigt werden soll.
190        /// </summary>
191        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
192
193        /// <summary>
194        /// Hier kommt das Darstellungs Control hin, Jungs!
195        /// </summary>
196        public UserControl Presentation
197        {
198          get { return null; }
199        }
200
201        public UserControl QuickWatchPresentation
202        {
203          get { return null; }
204        }
205
206        public void Stop()
207        {
208
209        }
210
211        public void PostExecution()
212        {
213            isPlayMode = false;
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            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
231        }
232
233        #endregion
234
235        #region Private methods
236        /// <summary>
237        /// Does the actual Caesar processing, i.e. encryption or decryption
238        /// </summary>
239        private void ProcessCaesar(CaesarMode mode)
240        {
241            CaesarSettings cfg = (CaesarSettings)this.settings;
242            StringBuilder output = new StringBuilder("");
243            string alphabet = cfg.AlphabetSymbols;
244
245            // in case we want don't consider case in the alphabet, we use only capital letters, hence transform
246            // the whole alphabet to uppercase
247            if (!cfg.CaseSensitiveAlphabet)
248            {
249                alphabet = cfg.AlphabetSymbols.ToUpper(); ;
250            }
251           
252
253            if (inputString != null)
254            {
255                for (int i = 0; i < inputString.Length; i++)
256                {
257                    // get plaintext char which is currently processed
258                    char currentchar = inputString[i];
259
260                    // remember if it is upper case (otherwise lowercase is assumed)
261                    bool uppercase = char.IsUpper(currentchar);
262
263                    // get the position of the plaintext character in the alphabet
264                    int ppos = 0;
265                    if (cfg.CaseSensitiveAlphabet)
266                    {
267                        ppos = alphabet.IndexOf(currentchar);
268                    }
269                    else
270                    {
271                        ppos = alphabet.IndexOf(char.ToUpper(currentchar));
272                    }
273 
274                    if (ppos >= 0)
275                    {
276                        // we found the plaintext character in the alphabet, hence we do the shifting
277                        int cpos = 0; ;
278                        switch (mode)
279                        {
280                            case CaesarMode.encrypt:
281                                cpos = (ppos + cfg.ShiftKey) % alphabet.Length;
282                                break;
283                            case CaesarMode.decrypt:
284                                cpos = (ppos - cfg.ShiftKey + alphabet.Length) % alphabet.Length;
285                                break;
286                        }
287
288                        // we have the position of the ciphertext character, hence just output it in the correct 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                    }
306                    else
307                    {
308                        // the plaintext character was not found in the alphabet, hence proceed with handling unknown characters
309                        switch ((CaesarSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
310                        {
311                            case CaesarSettings.UnknownSymbolHandlingMode.Ignore:
312                                output.Append(inputString[i]);
313                                break;
314                            case CaesarSettings.UnknownSymbolHandlingMode.Replace:
315                                output.Append('?');
316                                break;
317                        }
318
319                    }
320
321                    //show the progress
322                    if (OnPluginProgressChanged != null)
323                    {
324                      OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
325                    }
326
327                }
328                outputString = output.ToString();
329                OnPropertyChanged("OutputString");
330                OnPropertyChanged("OutputData");
331            }
332        }
333
334
335        /// <summary>
336        /// Handles log messages from the settings class
337        /// </summary>
338        private void Caesar_LogMessage(string msg, NotificationLevel loglevel)
339        {
340            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(msg, this, loglevel));
341            //if (OnGuiLogNotificationOccured != null)
342            //{
343            //    OnGuiLogNotificationOccured(this, new GuiLogEventArgs(msg, this, loglevel));
344            //}
345        }
346
347        /// <summary>
348        /// Handles re-execution events from settings class
349        /// </summary>
350        private void Caesar_ReExecute()
351        {
352            if (isPlayMode)
353                Execute();
354        }
355
356        #endregion
357
358        #region IPlugin Members
359
360#pragma warning disable 67
361                        public event StatusChangedEventHandler OnPluginStatusChanged;
362#pragma warning restore
363
364                public void Execute()
365        {
366            isPlayMode = true;
367
368            switch (settings.Action)
369            {
370                case 0:
371                    Caesar_LogMessage("encrypting", NotificationLevel.Debug);
372                    Encrypt();
373                    break;
374                case 1:
375                    Decrypt();
376                    break;
377                default:
378                    break;
379            }
380        }
381
382        public void Pause()
383        {
384           
385        }
386
387        #endregion
388
389    }
390}
Note: See TracBrowser for help on using the repository browser.