source: trunk/CrypPlugins/Substitution/Substitution.cs @ 2417

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

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

File size: 20.9 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 Cryptool.PluginBase.Cryptography;
23using Cryptool.PluginBase.IO;
24using System.Collections;
25using System.IO;
26using System.ComponentModel;
27using System.Windows.Controls;
28
29namespace Cryptool.Substitution
30{
31    [Author("Sebastian Przybylski", "sebastian@przybylski.org", "Uni-Siegen", "http://www.uni-siegen.de")]
32    [PluginInfo(false, "Substitution", "Substitution -- classic character-based mono-alphabetic substitution", "Substitution/DetailedDescription/Description.xaml",
33      "Substitution/Images/icon.png", "Substitution/Images/encrypt.png", "Substitution/Images/decrypt.png")]
34    [EncryptionType(EncryptionType.Classic)]
35    public class Substitution : IEncryption
36    {
37        #region Private variables
38
39        private SubstitutionSettings settings;
40        private string inputString;
41        private string outputString;
42        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
43
44        #endregion
45
46        #region Public interface
47
48        /// <summary>
49        /// Constructor
50        /// </summary>
51        public Substitution()
52        {
53            this.settings = new SubstitutionSettings(this);
54            ((SubstitutionSettings)(this.settings)).LogMessage += Substitution_LogMessage;
55        }
56
57        /// <summary>
58        /// Get or set all settings for this algorithm.
59        /// </summary>
60        public ISettings Settings
61        {
62            get { return (ISettings)this.settings; }
63            set { this.settings = (SubstitutionSettings)value; }
64        }
65
66        [PropertyInfo(Direction.OutputData, "Stream output","The string after processing with the Substitution cipher is converted to a stream. Default encoding is used.", null, true, false, QuickWatchFormat.Text, null)]
67        public CryptoolStream OutputData
68        {
69            get
70            {
71                if (outputString != null)
72                {
73                    CryptoolStream cs = new CryptoolStream();
74                    listCryptoolStreamsOut.Add(cs);
75                    cs.OpenRead(this.GetPluginInfoAttribute().Caption, Encoding.Default.GetBytes(outputString.ToCharArray()));
76                    return cs;
77                }
78                else
79                {
80                    return null;
81                }
82            }
83            set { }
84        }
85
86        [PropertyInfo(Direction.InputData, "Text input","Input a string to be processed by the Substitution cipher", null, true, false, QuickWatchFormat.Text, null)]
87        public string InputString
88        {
89            get { return this.inputString; }
90            set 
91            {
92                if (value != inputString)
93                {
94                    this.inputString = value;
95                    OnPropertyChanged("InputString");
96                }
97            }
98        }
99
100        [PropertyInfo(Direction.OutputData, "Text output", "The string after processing with the Substitution cipher", null, true, false,QuickWatchFormat.Text, null)]
101        public string OutputString
102        {
103            get { return this.outputString; }
104            set
105            {
106                outputString = value;
107                OnPropertyChanged("OutputString");
108            }
109        }
110
111        [PropertyInfo(Direction.InputData, "Plaintext Alphabet","Input a string containing the plaintext-alphabet which should be used by Substitution.\nIf no alphabet is provided on the input, the internal alphabet will be used.", null, false, false, QuickWatchFormat.Text, null)]
112        public string InputAlphabet
113        {
114            get { return ((SubstitutionSettings)this.settings).AlphabetSymbols; }
115            set
116            {
117                if (value != null && value != settings.AlphabetSymbols)
118                {
119                    ((SubstitutionSettings)this.settings).AlphabetSymbols = value;
120                    OnPropertyChanged("InputAlphabet");
121                }
122            }
123        }
124
125        [PropertyInfo(Direction.InputData, "Key (or substitution/cipher alphabet)","Same setting as key value in settings. \nIf you use a key shorter than the plaintext-alphabet, \nthe remaining characters of the cipher-alphabet will be filled up \naccording to the setting in the plug-ins settings pane. \nIf your key has the same length as the plaintext-alphabet, \nyou can perform the most general monoalphabetic substitution.", null, false, false, QuickWatchFormat.Text, null)]
126        public string KeyValue
127        {
128            get { return settings.KeyValue; }
129            set
130            {
131                if (value != settings.KeyValue)
132                {
133                    settings.KeyValue = value;
134                }
135            }
136        }
137
138        /// <summary>
139        /// Substitution encryption
140        /// </summary>
141        public void Encrypt()
142        {
143            if(inputString != null)
144            {
145                SubstitutionSettings cfg = (SubstitutionSettings)this.settings;
146                StringBuilder output = new StringBuilder(string.Empty);
147
148                string alphabet = cfg.AlphabetSymbols;
149
150                //in case we don't want consider case in the alphabet, we use only capital letters, hence transform
151                //the whole alphabet to uppercase
152                if(!cfg.CaseSensitiveAlphabet)
153                {
154                    alphabet = cfg.AlphabetSymbols.ToUpper();
155                }
156
157                for (int i = 0; i < inputString.Length; i++)
158                {
159                    //get plaintext char which is currently processed
160                    char currentchar = inputString[i];
161
162                    //remember if it is upper (otherwise lowercase is assumed)
163                    bool uppercase = char.IsUpper(currentchar);
164
165                    //get the position of the plaintext in the alphabet
166                    int ppos = 0;
167                    if (cfg.CaseSensitiveAlphabet)
168                    {
169                        ppos = alphabet.IndexOf(currentchar);
170                    }
171                    else
172                    {
173                        ppos = alphabet.IndexOf(char.ToUpper(currentchar));
174                    }
175
176                    if (ppos >= 0)
177                    {
178                        //we found the plaintext character in the alphabet
179                        if (cfg.CaseSensitiveAlphabet)
180                        {
181                            output.Append(cfg.CipherAlphabet[ppos]);
182                        }
183                        else
184                        {
185                            if (uppercase)
186                            {
187                                output.Append(char.ToUpper(cfg.CipherAlphabet[ppos]));
188                            }
189                            else
190                            {
191                                output.Append(char.ToLower(cfg.CipherAlphabet[ppos]));
192                            }
193                        }
194                    }
195                    else
196                    {
197                        //the plaintext character was not found in the alphabet, hence proceed whith handling unknown characters
198                        switch ((SubstitutionSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
199                        {
200                            case SubstitutionSettings.UnknownSymbolHandlingMode.Ignore:
201                                output.Append(inputString[i]);
202                                break;
203                            case SubstitutionSettings.UnknownSymbolHandlingMode.Remove:
204                                break;
205                            case SubstitutionSettings.UnknownSymbolHandlingMode.Replace:
206                                output.Append('?');
207                                break;
208                            default:
209                                break;
210                        }
211                    }
212
213                    //show the progress
214                    if (OnPluginProgressChanged != null)
215                    {
216                        OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
217                    }
218                }
219                outputString = output.ToString();
220                OnPropertyChanged("OutputString");
221                OnPropertyChanged("OutputData");
222            }
223        }
224
225        /// <summary>
226        /// Substitution decryption
227        /// </summary>
228        public void Decrypt()
229        {
230            if (inputString != null)
231            {
232                SubstitutionSettings cfg = (SubstitutionSettings)this.settings;
233                StringBuilder output = new StringBuilder(string.Empty);
234
235                string alphabet = cfg.AlphabetSymbols;
236
237                //in case we do not want consider case in the alphabet, we use only capital letter, hence transform
238                //the whole alphabet to uppercase
239                if (!cfg.CaseSensitiveAlphabet)
240                {
241                    alphabet = cfg.AlphabetSymbols.ToUpper();
242                }
243
244                for (int i = 0; i < inputString.Length; i++)
245                {
246                    //get plaintext char which is currently processed
247                    char currentchar = inputString[i];
248
249                    //remember if it is upper case (otherwise lowercase is assumed)
250                    bool uppercase = char.IsUpper(currentchar);
251
252                    //get the position of the cipher text character in the alphabet
253                    int ppos = 0;
254                    if (cfg.CaseSensitiveAlphabet)
255                    {
256                        ppos = cfg.CipherAlphabet.IndexOf(currentchar);
257                    }
258                    else
259                    {
260                        ppos = cfg.CipherAlphabet.IndexOf(char.ToUpper(currentchar));
261                    }
262
263                    if (ppos >= 0)
264                    {
265                        //we found the cipher text character in the alphabet
266                        if (cfg.CaseSensitiveAlphabet)
267                        {
268                            output.Append(alphabet[ppos]);
269                        }
270                        else
271                        {
272                            //find the right plain text char and append it to the output
273                            if (uppercase)
274                            {
275                                output.Append(char.ToUpper(alphabet[ppos]));
276                            }
277                            else
278                            {
279                                output.Append(char.ToLower(alphabet[ppos]));
280                            }
281                        }
282                    }
283                    else
284                    {
285                        //the ciphertext character was not found in the alphabet, hence proceed with handling unknown characters
286                        switch ((SubstitutionSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
287                        {
288                            case SubstitutionSettings.UnknownSymbolHandlingMode.Ignore:
289                                output.Append(inputString[i]);
290                                break;
291                            case SubstitutionSettings.UnknownSymbolHandlingMode.Remove:
292                                break;
293                            case SubstitutionSettings.UnknownSymbolHandlingMode.Replace:
294                                output.Append('?');
295                                break;
296                            default:
297                                break;
298                        }
299                    }
300
301                    //show the progress
302                    if (OnPluginProgressChanged != null)
303                    {
304                        OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
305                    }
306                }
307                outputString = output.ToString();
308                OnPropertyChanged("OutputString");
309                OnPropertyChanged("OutputData");
310            }
311        }
312
313        #endregion
314
315        public void GuiLogMessage(string message, NotificationLevel loglevel)
316        {
317            if (OnGuiLogNotificationOccured != null)
318                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
319        }
320
321        #region IPlugin members
322
323        public void Initialize()
324        {
325        }
326
327        public void Dispose()
328        {
329            foreach (CryptoolStream stream in listCryptoolStreamsOut)
330            {
331                stream.Close();
332            }
333            listCryptoolStreamsOut.Clear();
334        }
335
336        public bool HasChanges
337        {
338            get { return settings.HasChanges; }
339            set { settings.HasChanges = value; }
340        }
341
342        /// <summary>
343        /// Fire if progress bar status was changed
344        /// </summary>
345        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
346
347        /// <summary>
348        /// Fire if a new message has to be shown in the status bar
349        /// </summary>
350        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
351
352        public UserControl Presentation
353        {
354            get { return null; }
355        }
356
357        public UserControl QuickWatchPresentation
358        {
359            get { return null; }
360        }
361
362        public void Stop()
363        {
364        }
365
366        public void PostExecution()
367        {
368            Dispose();
369        }
370
371        public void PreExecution()
372        {
373            Dispose();
374        }
375
376        #endregion
377
378        #region INotifyPropertyChanged Members
379
380        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
381
382        public void OnPropertyChanged(string name)
383        {
384            if (PropertyChanged != null)
385            {
386                PropertyChanged(this, new PropertyChangedEventArgs(name));
387            }
388        }
389
390        #endregion
391
392        #region Private methods
393
394        private void Substitution_LogMessage(string msg, NotificationLevel logLevel)
395        {
396            if (OnGuiLogNotificationOccured != null)
397            {
398                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(msg, this, logLevel));
399            }
400        }
401
402        #endregion
403
404        #region IPlugin Members
405
406        public event StatusChangedEventHandler OnPluginStatusChanged;
407
408        public void Execute()
409        {
410            foreach (char c in settings.KeyValue)
411            {
412                if (!settings.AlphabetSymbols.Contains(c))
413                {
414                    GuiLogMessage("Key contains characters that are not part of the alphabet!", NotificationLevel.Error);
415                    return;
416                }
417            }
418
419            switch (settings.Action)
420            {
421                case 0:
422                    Encrypt();
423                    break;
424                case 1:
425                    Decrypt();
426                    break;
427                default:
428                    break;
429            }
430        }
431
432        public void Pause()
433        {
434        }
435
436        #endregion
437        ///// <summary>
438        ///// Substitution encryption
439        ///// </summary>
440        ///// <param name="inputData">The input data to encrypt</param>
441        ///// <param name="key">Key which the encryption uses</param>
442        ///// <param name="alphabet">Alphabet which the encryption uses</param>
443        ///// <returns>The encrypted data as an int array</returns>
444        //public Stream Encrypt(IEncryptionAlgorithmSettings settings)
445        //{
446        //    AlphabetConverter alphConv = new AlphabetConverter();
447        //    int[] inputData = alphConv.StreamToIntArray(((SubstitutionSettings)settings).InputData);
448        //    int[] outputData = new int[inputData.Length];
449        //    int[] alphCipher = getAlphCipher(removeDuplicateChars(((SubstitutionSettings)settings).Key), ((SubstitutionSettings)settings).Alphabet);
450
451        //    for (int i = 0; i < inputData.Length; i++)
452        //    {
453        //        for (int j = 0; j < ((SubstitutionSettings)settings).Alphabet.Length; j++)
454        //        {
455        //            if (((SubstitutionSettings)settings).Alphabet[j] == inputData[i])
456        //            {
457        //                outputData[i] = alphCipher[j];
458        //                break;
459        //            }
460        //        }
461        //    }
462        //    return alphConv.intArrayToStream(outputData);
463        //}
464
465        ///// <summary>
466        ///// Substitution decryption
467        ///// </summary>
468        ///// <param name="inputData">The input data to decrypt</param>
469        ///// <param name="key">Key which the encryption uses</param>
470        ///// <param name="alphabet">Alphabet which the encryption uses</param>
471        ///// <returns>The decrypted data as an int array</returns>
472        //public Stream Decrypt(IEncryptionAlgorithmSettings settings)
473        //{
474        //    AlphabetConverter alphConv = new AlphabetConverter();
475        //    int[] inputData = alphConv.StreamToIntArray(((SubstitutionSettings)settings).InputData);
476        //    int[] outputData = new int[inputData.Length];
477        //    int[] alphCipher = getAlphCipher(removeDuplicateChars(((SubstitutionSettings)settings).Key), ((SubstitutionSettings)settings).Alphabet);
478
479        //    for (int i = 0; i < inputData.Length; i++)
480        //    {
481        //        for (int j = 0; j < ((SubstitutionSettings)settings).Alphabet.Length; j++)
482        //        {
483        //            if (alphCipher[j] == inputData[i])
484        //            {
485        //                outputData[i] = ((SubstitutionSettings)settings).Alphabet[j];
486        //                break;
487        //            }
488        //        }
489        //    }
490        //    return alphConv.intArrayToStream(outputData);
491        //}
492
493        ///// <summary>
494        ///// Build alphabet cipher
495        ///// </summary>
496        ///// <param name="key">used key</param>
497        ///// <param name="alphabet">The plain alphabet</param>
498        ///// <returns>Alphabet for en-/decryption as an int array</returns>
499        //private int[] getAlphCipher(int[] key, int[] alphabet)
500        //{
501        //    int count = 0;
502        //    bool found;
503        //    int[] alphCipher = new int[alphabet.Length];
504
505        //    for (int i = 0; i < key.Length; i++)
506        //    {
507        //        alphCipher[i] = key[i];
508        //    }
509
510        //    for (int i = 0; i < alphabet.Length; i++)
511        //    {
512        //        found = false;
513        //        for (int j = 0; j < key.Length && !found; j++)
514        //        {
515        //            if (alphabet[i] == key[j])
516        //            {
517        //                found = true;
518        //                count++;
519        //            }
520        //        }
521        //        if (!found)
522        //        {
523        //            alphCipher[i + key.Length - count] = alphabet[i];
524        //        }
525        //    }
526
527        //    return alphCipher;
528        //}
529
530        ///// <summary>
531        ///// Remove duplicate characters from the key array
532        ///// </summary>
533        ///// <param name="key">The key array</param>
534        ///// <returns>The key array without duplicate characters</returns>
535        //private int[] removeDuplicateChars(int[] key)
536        //{
537        //    bool found;
538        //    int[] newKey;
539        //    ArrayList alKey = new ArrayList();
540           
541        //    for (int i = 0; i < key.Length; i++)
542        //    {
543        //        found = false;
544        //        for (int j = 0; j < alKey.Count; j++)
545        //        {
546        //            if (key[i] == (int)alKey[j])
547        //            {
548        //                found = true;
549        //                break;
550        //            }
551        //        }
552        //        if (!found)
553        //        {
554        //            alKey.Add(key[i]);
555        //        }
556        //    }
557
558        //    newKey = new int[alKey.Count];
559        //    for (int i = 0; i < alKey.Count; i++)
560        //    {
561        //        newKey[i] = (int)alKey[i];
562        //    }
563
564        //    return newKey;
565        //}
566
567    }
568}
Note: See TracBrowser for help on using the repository browser.