source: trunk/CrypPlugins/Substitution/SubstitutionSettings.cs @ 2214

Last change on this file since 2214 was 2062, checked in by Sven Rech, 11 years ago
  • fixed quadratic sieve time overflow bug
  • fixed substitution case sensitivity behaviors
File size: 14.3 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 System.IO;
22using Cryptool.PluginBase;
23using System.ComponentModel;
24
25namespace Cryptool.Substitution
26{
27    public class SubstitutionSettings : ISettings
28    {
29        #region Public Caesar specific interface
30
31        /// <summary>
32        /// We use this delegate to send log messages from the settings class to the Substitution plugin
33        /// </summary>
34        /// <param name="sender"></param>
35        /// <param name="msg"></param>
36        /// <param name="logLevel"></param>
37        public delegate void SubstitutionLogMessage(string msg, NotificationLevel logLevel);
38
39        /// <summary>
40        /// An enumaration for the different modes of dealing with unknown characters
41        /// </summary>
42        public enum UnknownSymbolHandlingMode { Ignore = 0, Remove = 1, Replace = 2 };
43
44        /// <summary>
45        /// An enumaration fot the different key variante modes of refilling the cipher alphabet
46        /// </summary>
47        public enum KeyVariantMode { RestCharAscending = 0, RestCharDescending = 1, FixKeyAtbash = 2 };
48       
49        /// <summary>
50        /// Fire if a new message has to be shown in the status bar
51        /// </summary>
52        public event SubstitutionLogMessage LogMessage;
53
54        /// <summary>
55        /// Retrieves the current settings whether the alphabet shoudl be treated as case sensitive or not
56        /// </summary>
57        [PropertySaveOrder(0)]
58        public bool CaseSensitiveAlphabet
59        {
60            get
61            {
62                if (caseSensitiveAlphabet == 0) return false;
63                else return true;
64            }
65            set { } //read only
66        }
67
68        /// <summary>
69        /// Return true if some settings habe been changed. This value should be set externally to false e.g.
70        /// when a project was saved.
71        /// </summary>
72        [PropertySaveOrder(1)]
73        public bool HasChanges
74        {
75            get { return hasChanges; }
76            set { hasChanges = value; }
77        }
78
79        #endregion
80
81        #region Private variables
82
83        private bool hasChanges;
84        private int selectedAction = 0;
85        private KeyVariantMode keyVariant = KeyVariantMode.RestCharAscending;
86        private string upperAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
87        private string lowerAlphabet = "abcdefghijklmnopqrstuvwxyz";
88        private string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
89        private string cipherAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
90        private string keyValue;
91        private UnknownSymbolHandlingMode unknowSymbolHandling = UnknownSymbolHandlingMode.Ignore;
92        private int caseSensitiveAlphabet = 0; //0=case insensitive, 1 = case sensitive
93        private Substitution substitution;
94
95        #endregion
96
97        public SubstitutionSettings(Substitution substitution)
98        {
99            this.substitution = substitution;
100        }
101
102        #region Private methods
103
104        private string removeEqualChars(string value)
105        {
106            int length = value.Length;
107
108            for (int i = 0; i < length; i++)
109            {
110                for (int j = i + 1; j < length; j++)
111                {
112                    if (value[i] == value[j] || (!CaseSensitiveAlphabet & (char.ToUpper(value[i]) == char.ToUpper(value[j]))))
113                    {
114                        LogMessage("Removing duplicate letter: \'" + value[j] + "\' from alphabet!", NotificationLevel.Warning);
115                        value = value.Remove(j, 1);
116                        j--;
117                        length--;
118                    }
119                }
120            }
121            return value;
122        }
123
124        private void setCipherAlphabet(string value)
125        {
126            foreach (char c in value)
127            {
128                if (!alphabet.Contains(c))
129                    substitution.GuiLogMessage("Key contains characters that are not part of the alphabet!", NotificationLevel.Error);
130            }
131
132            try
133            {
134                string a = null;
135                bool found;
136                switch (keyVariant)
137                {
138                    case KeyVariantMode.RestCharAscending:
139                        a = value;
140                        for (int i = 0; i < alphabet.Length; i++)
141                        {
142                            found = false;
143                            for (int j = 0; j < a.Length; j++)
144                            {
145                                if (alphabet[i] == a[j])
146                                {
147                                    found = true;
148                                    break;
149                                }
150                            }
151                            if (!found)
152                                a += alphabet[i];
153                        }
154                        break;
155                    case KeyVariantMode.RestCharDescending:
156                        a = value;
157                        for (int i = alphabet.Length - 1; i >= 0; i--)
158                        {
159                            found = false;
160                            for (int j = 0; j < a.Length; j++)
161                            {
162                                if (alphabet[i] == a[j])
163                                {
164                                    found = true;
165                                    break;
166                                }
167                            }
168                            if (!found)
169                                a += alphabet[i];
170                        }
171                        break;
172                    case KeyVariantMode.FixKeyAtbash:
173                        a = string.Empty;
174                        for (int i = alphabet.Length - 1; i >= 0; i--)
175                            a += alphabet[i];
176                        break;
177                }
178                CipherAlphabet = removeEqualChars(a);
179                OnPropertyChanged("CipherAlphabet");
180            }
181            catch (Exception e)
182            {
183                LogMessage("Bad input \"" + value + "\"! (" + e.Message + ") Reverting to " + alphabet + "!", NotificationLevel.Error);
184                OnPropertyChanged("CipherAlphabet");
185            }
186        }
187
188        #endregion
189
190        #region Algorithm settings properties (visible in the Settings pane)
191
192        [PropertySaveOrder(2)]
193        [ContextMenu("Action","Select the Algorithm action", 1, DisplayLevel.Beginner, ContextMenuControlType.ComboBox, new int[] {1,2}, "Encrypt","Decrypt")]
194        [TaskPane("Action", "Select the Algorithm action", null, 1, false, DisplayLevel.Beginner, ControlType.ComboBox, new string[] {"Encrypt","Decrypt"})]
195        public int Action
196        {
197            get { return this.selectedAction; }
198            set
199            {
200                if (value != selectedAction) HasChanges = true;
201                this.selectedAction = value;
202                OnPropertyChanged("Action");
203            }
204        }
205
206        [PropertySaveOrder(3)]
207        [TaskPane("Key value (multiple letter)", "Enter one or multiple letters as the key.", null, 2, false, DisplayLevel.Experienced, ControlType.TextBox,"",null)]
208        public string KeyValue
209        {
210            get { return this.keyValue; }
211            set 
212            {
213                this.keyValue = value;
214                setCipherAlphabet(keyValue);
215                OnPropertyChanged("KeyValue");
216                OnPropertyChanged("AlphabetSymbols");
217            }
218           
219        }
220
221        [PropertySaveOrder(4)]
222        [ContextMenu("Unknown symbol handling","What should be done with ecountered characters at the input which are not in the alphabet?",3,DisplayLevel.Expert,ContextMenuControlType.ComboBox, null, new string[] {"Ignore (leave unmodified)", "Remove","Replace with \'?\'"})]
223        [TaskPane("Unknown symbol handling", "What should be done with ecountered characters at the input which are not in the alphabet?", null, 3, false, DisplayLevel.Expert, ControlType.ComboBox, new string[] {"Ignore (leave unmodified)", "Remove","Replace with \'?\'"})]
224        public int UnknownSymbolHandling
225        {
226            get { return (int)this.unknowSymbolHandling; }
227            set
228            {
229                if ((UnknownSymbolHandlingMode)value != unknowSymbolHandling) HasChanges = true;
230                this.unknowSymbolHandling = (UnknownSymbolHandlingMode)value;
231                OnPropertyChanged("UnknownSymbolHandling");
232            }
233        }
234
235        [PropertySaveOrder(5)]
236        [ContextMenu("Alphabet case sensitivity","Should upper and lower case be treated differently? (Should a == A)",4,DisplayLevel.Expert, ContextMenuControlType.ComboBox,null, new string[] {"Case insensitive","Case sensitive"})]
237        [TaskPane("Alphabet case sensitivity","Should upper and lower case be treated differently? (Should a == A)", null, 4, false, DisplayLevel.Expert, ControlType.ComboBox, new string[] {"Case insensitive","Case sensitive"})]
238        public int AlphabetCase
239        {
240            get { return this.caseSensitiveAlphabet; }
241            set
242            {
243                if (value != caseSensitiveAlphabet) hasChanges = true;
244                this.caseSensitiveAlphabet = value;
245                if (value == 0)
246                {
247                    if (alphabet == (upperAlphabet + lowerAlphabet))
248                    {
249                        alphabet = upperAlphabet;
250                        LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + "Symbols)", NotificationLevel.Info);
251                        OnPropertyChanged("AlphabetSymbols");
252                        setCipherAlphabet(keyValue);
253                    }
254                }
255                else
256                {
257                    if (alphabet == upperAlphabet)
258                    {
259                        alphabet = upperAlphabet + lowerAlphabet;
260                        LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
261                        OnPropertyChanged("AlphabetSymbols");
262                        setCipherAlphabet(keyValue);
263                    }
264                }
265
266                //remove equal characters from the current alphabet
267                string a = alphabet;
268                alphabet = removeEqualChars(alphabet);
269
270                if (a != alphabet)
271                {
272                    OnPropertyChanged("AlphabetSymbols");
273                    LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
274                }
275                OnPropertyChanged("AlphabetCase");
276            }
277        }
278
279        [PropertySaveOrder(6)]
280        [ContextMenu("Key variant","Select the key variant for the cipher alphabet",5,DisplayLevel.Expert,ContextMenuControlType.ComboBox,null,new string[] {"Remaining characters are filled in ascending order","Remaining characters are filld in descending order","Atbash (the encryption is using a fixed key)"})]
281        [TaskPane("Key variant","Select the key variant for the cipher alphabet", null, 5, false, DisplayLevel.Expert, ControlType.ComboBox,new string[] {"Remaining characters are filled in ascending order","Remaining characters are in descending order","Atbash (the encryption is using a fixed key)"})]
282        public int KeyVariant
283        {
284            get { return (int)this.keyVariant; }
285            set
286            {
287                if ((KeyVariantMode)value != keyVariant) HasChanges = true;
288                this.keyVariant = (KeyVariantMode)value;
289                setCipherAlphabet(keyValue);
290                OnPropertyChanged("KeyVariant");
291            }
292        }
293
294        [PropertySaveOrder(7)]
295        [TaskPane("Alphabet","This is the used alphabet.", null, 5, false, DisplayLevel.Expert,ControlType.TextBox,"")]
296        public string AlphabetSymbols
297        {
298            get { return this.alphabet; }
299            set
300            {
301                string a = removeEqualChars(value);
302                if (a.Length == 0) // cannot accept empty alphabets
303                {
304                    LogMessage("Ignoring empty alphabet from user! Using previous alphabet: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
305                }
306                else if (!alphabet.Equals(a))
307                {
308                    HasChanges = true;
309                    this.alphabet = a;
310                    setCipherAlphabet(keyValue); //re-evaluate if the key value is still within the range
311                    LogMessage("Accepted new alphabet from user: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
312                    OnPropertyChanged("AlphabetSymbols");
313                }
314            }
315        }
316
317        [PropertySaveOrder(8)]
318        [TaskPane("Cipher alphabet", "This is the used cipher alphabet.", null, 6, false, DisplayLevel.Expert, ControlType.TextBox, "")]
319        public string CipherAlphabet
320        {
321            get { return this.cipherAlphabet; }
322            set 
323            {
324                this.cipherAlphabet = value;
325                OnPropertyChanged("CipherAlphabet");
326            }
327        }
328
329        #endregion
330
331        #region INotifyPropertyChanged Members
332
333        public event PropertyChangedEventHandler PropertyChanged;
334
335        protected void OnPropertyChanged(string name)
336        {
337            if (PropertyChanged != null)
338            {
339                PropertyChanged(this, new PropertyChangedEventArgs(name));
340            }
341        }
342
343        #endregion
344    }
345}
Note: See TracBrowser for help on using the repository browser.