source: trunk/CrypPlugins/ADFGVX/ADFGVX.cs @ 2424

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

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

File size: 21.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 Cryptool.PluginBase.Cryptography;
23using Cryptool.PluginBase.IO;
24using Cryptool.PluginBase.Miscellaneous;
25using System.Collections;
26using System.IO;
27using System.ComponentModel;
28
29namespace Cryptool.ADFGVX
30{
31    [Author("Sebastian Przybylski","sebastian@przybylski.org","Uni-Siegen","http://www.uni-siegen.de")]
32    [PluginInfo(false,"ADFGVX",
33        "ADFGVX -- cipher used in WW1, combining substitution and transposition",
34        "ADFGVX/DetailedDescription/Description.xaml", "ADFGVX/Images/icon.png", "ADFGVX/Images/encrypt.png", "ADFGVX/Images/decrypt.png")]
35    [EncryptionType(EncryptionType.Classic)]
36    public class ADFGVX : IEncryption
37    {
38        #region Private variables
39
40        private ADFGVXSettings settings;
41        private string inputString;
42        private string outputString;
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 ADFGVX()
53        {
54            this.settings = new ADFGVXSettings();
55            ((ADFGVXSettings)(this.settings)).LogMessage += ADFGVX_LogMessage;
56        }
57
58        /// <summary>
59        /// Get or set settings for the algorithm
60        /// </summary>
61        public ISettings Settings
62        {
63            get { return (ISettings)this.settings; }
64            set { this.settings = (ADFGVXSettings)value; }
65        }
66
67        [PropertyInfo(Direction.OutputData, "Stream output", "The string after processing with the Caesar cipher is converted to a stream. Default encoding is used.", "", 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 ADFGVX cipher", "", 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 ADFGVX cipher", "", 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 alphabet which should be used by ADFGVX.\nIf no alphabet is provided on this input, the internal alphabet will be used.", "", false, false, QuickWatchFormat.Text, null)]
113        public string InputAlphabet
114        {
115            get { return ((ADFGVXSettings)this.settings).SubstitutionMatrix; }
116            set
117            {
118                if (value != null && value != settings.SubstitutionMatrix)
119                {
120                    if (value.Length > settings.SubstitutionMatrix.Length)
121                    {
122                        value = value.Remove(settings.SubstitutionMatrix.Length);
123                        ADFGVX_LogMessage("Input alphabet to long! Reduce alphabet to " + settings.SubstitutionMatrix.Length.ToString() + " characters!", NotificationLevel.Info);
124                        ((ADFGVXSettings)this.settings).SubstitutionMatrix = value;
125                    }
126                    else if (value.Length < settings.SubstitutionMatrix.Length)
127                    {
128                        ADFGVX_LogMessage("Input alphabet to short! The alphabet must have " + settings.SubstitutionMatrix.Length.ToString() + " characters!", NotificationLevel.Info);
129                        ((ADFGVXSettings)this.settings).SubstitutionMatrix = value;
130                    }
131                    else
132                    {
133                        ((ADFGVXSettings)this.settings).SubstitutionMatrix = value;
134                    }
135                    OnPropertyChanged("InputAlphabet");
136                }
137            }
138        }
139
140        [PropertyInfo(Direction.InputData, "Transposition password", "Same setting as Transposition password in Settings-Pane but as dynamic input.", "", false, false, QuickWatchFormat.Text, null)]
141        public string TranspositionPassword
142        {
143            get { return settings.TranspositionPass; }
144            set
145            {
146                if (value != settings.TranspositionPass)
147                {
148                    settings.TranspositionPass = value;
149                }
150            }
151        }
152
153        #endregion
154
155        /// <summary>
156        /// ADFGVX encryptor
157        /// Attribute for action needed!
158        /// </summary>
159        public void Encrypt()
160        {
161            if (inputString != null)
162            {
163                string strInput;
164
165                //Change input string to upper or lower case
166                if (!settings.CaseSensitiveAlphabet)
167                    strInput = InputString.ToUpper();
168                else
169                    strInput = InputString.ToLower();
170
171
172                //remove or replace non alphabet char
173                switch ((ADFGVXSettings.UnknownSymbolHandlingMode)settings.UnknownSymbolHandling)
174                {
175                    case ADFGVXSettings.UnknownSymbolHandlingMode.Remove:
176                        strInput = removeNonAlphChar(strInput);
177                        break;
178                    case ADFGVXSettings.UnknownSymbolHandlingMode.Replace:
179                        strInput = replaceNonAlphChar(strInput);
180                        break;
181                    default:
182                        break;
183                }
184
185
186
187                string alphCipher = settings.SubstitutionMatrix;
188                StringBuilder strOutput = new StringBuilder(string.Empty);
189
190                //1. Step - Substitution
191                for (int i = 0; i < strInput.Length; i++)
192                {
193                    for (int j = 0; j < alphCipher.Length; j++)
194                    {
195                        if (alphCipher[j] == strInput[i])
196                        {
197                            int line = j / 6;
198                            int column = j % 6;
199                            String pair = string.Empty;
200                            switch (line)
201                            {
202                                case 0:
203                                    pair = "A";
204                                    break;
205                                case 1:
206                                    pair = "D";
207                                    break;
208                                case 2:
209                                    pair = "F";
210                                    break;
211                                case 3:
212                                    pair = "G";
213                                    break;
214                                case 4:
215                                    pair = "V";
216                                    break;
217                                case 5:
218                                    pair = "X";
219                                    break;
220                                default:
221                                    break;
222                            }
223                            switch (column)
224                            {
225                                case 0:
226                                    pair += "A";
227                                    break;
228                                case 1:
229                                    pair += "D";
230                                    break;
231                                case 2:
232                                    pair += "F";
233                                    break;
234                                case 3:
235                                    pair += "G";
236                                    break;
237                                case 4:
238                                    pair += "V";
239                                    break;
240                                case 5:
241                                    pair += "X";
242                                    break;
243                                default:
244                                    break;
245                            }
246                            strOutput.Append(pair[0]);
247                            strOutput.Append(pair[1]);
248                        }
249                    }
250                    //show the progress
251                    if (OnPluginProgressChanged != null)
252                    {
253                        OnPluginProgressChanged(this, new PluginProgressEventArgs(i, strInput.Length - 1));
254                    }
255                }
256                //2. Step - Transposition
257
258                int[] newOrder = getOrder(settings.CleanTranspositionPass);
259                StringBuilder strOutputData = new StringBuilder(string.Empty);
260
261                for (int i = 0; i < newOrder.Length; i++)
262                {
263                    int tempOrder = newOrder[i];
264                    for (int j = tempOrder; j < strOutput.Length; j=j+newOrder.Length)
265                    {
266                        strOutputData.Append(strOutput[j]);
267                    }
268
269                }
270                OutputString = strOutputData.ToString();
271                OnPropertyChanged("OutputString");
272                OnPropertyChanged("OutputData");
273            }
274        }
275
276        /// <summary>
277        /// ADFGVX decryptor
278        /// Attribute for action needed!
279        /// </summary>
280        public void Decrypt()
281        {
282            if (inputString != null)
283            {
284                string strInput;
285
286                //Change input string to upper or lower case
287                if (!settings.CaseSensitiveAlphabet)
288                    strInput = inputString.ToUpper();
289                else
290                    strInput = inputString.ToLower();
291
292                //check if input string consists only cipher chars
293                if (!checkForRightCipherChar(strInput))
294                {
295                    ADFGVX_LogMessage("The cipher text does not consists only of cipher characters : \'A\',\'D\',\'F\',\'G\',\'V\',\'X\' !", NotificationLevel.Error);
296                    return;
297                }
298
299                string alphCipher = settings.SubstitutionMatrix;
300                StringBuilder strOutput = new StringBuilder(string.Empty);
301
302                //1. Step Transposition
303                int[] order = getOrder(settings.CleanTranspositionPass);
304                char[] strOutputData = new char[strInput.Length];
305
306                int count = 0;
307                for (int i = 0; i < order.Length; i++)
308                {
309                    int tempOrder = order[i];
310                    for (int j = tempOrder; j < strInput.Length;j=j+order.Length)
311                    {
312                        strOutputData[j] = strInput[count];
313                        count++;
314                    }
315                }
316
317                for (int i = 0; i < strOutputData.Length; i++)
318                {
319                    char[] pair = new char[2];
320                    int line = 0;
321                    int column = 0;
322                    pair[0] = strOutputData[i];
323                    i++;
324                    pair[1] = strOutputData[i];
325
326                    switch (pair[0])
327                    {
328                        case 'A':
329                            line = 0;
330                            break;
331                        case 'D':
332                            line = 1;
333                            break;
334                        case 'F':
335                            line = 2;
336                            break;
337                        case 'G':
338                            line = 3;
339                            break;
340                        case 'V':
341                            line = 4;
342                            break;
343                        case 'X':
344                            line = 5;
345                            break;
346                        default:
347                            break;
348                    }
349                    switch (pair[1])
350                    {
351                        case 'A':
352                            column = 0;
353                            break;
354                        case 'D':
355                            column = 1;
356                            break;
357                        case 'F':
358                            column = 2;
359                            break;
360                        case  'G':
361                            column = 3;
362                            break;
363                        case 'V':
364                            column = 4;
365                            break;
366                        case 'X':
367                            column = 5;
368                            break;
369                        default:
370                            break;
371                    }
372                    int ch = line * 6 + column;
373                    strOutput.Append(alphCipher[ch]);
374
375                    //show the progress
376                    if (OnPluginProgressChanged != null)
377                    {
378                        OnPluginProgressChanged(this, new PluginProgressEventArgs(i, strOutputData.Length - 1));
379                    }
380                }
381                OutputString = strOutput.ToString();
382                OnPropertyChanged("OutputString");
383                OnPropertyChanged("OutputData");
384            }
385        }
386
387        /// <summary>
388        /// Remove all ADFGVX char and check if any non cipher char exists,
389        /// if so, do not decrypt
390        /// </summary>
391        /// <param name="value"></param>
392        /// <returns></returns>
393        private bool checkForRightCipherChar(string value)
394        {
395            char[] trimChars = {'A','D','F','G','V','X'};
396            value = value.Trim(trimChars);
397
398            if (value.Length > 0) return false;
399            else return true;
400        }
401
402        /// <summary>
403        /// Replace all non alphabet characters
404        /// </summary>
405        /// <param name="value"></param>
406        /// <returns></returns>
407        private string replaceNonAlphChar(string value)
408        {
409            int length = value.Length;
410            StringBuilder sb = new StringBuilder(string.Empty);
411
412            for (int i = 0; i < length; i++)
413            {
414                string curChar = value[i].ToString();
415
416                if (settings.SubstitutionMatrix.Contains(curChar))
417                {
418                    sb.Append(curChar);
419                }
420                else
421                {
422                    if (!settings.CaseSensitiveAlphabet)
423                    {
424                        if (value[i] == 'Ä')
425                            sb.Append("AE");
426                        else if (value[i] == 'Ö')
427                            sb.Append("OE");
428                        else if (value[i] == 'Ü')
429                            sb.Append("UE");
430                        else if (value[i] == 'ß')
431                            sb.Append("SS");
432                    }
433                    else
434                    {
435                        if (value[i] == 'À')
436                            sb.Append("ae");
437                        else if (value[i] == 'ö')
438                            sb.Append("oe");
439                        else if (value[i] == 'ÃŒ')
440                            sb.Append("ue");
441                        else if (value[i] == 'ß')
442                            sb.Append("ss");
443                    }
444                }
445            }
446            return sb.ToString();
447        }
448
449        /// <summary>
450        /// Remove all non alphabet characters
451        /// </summary>
452        /// <param name="value"></param>
453        /// <returns></returns>
454        private string removeNonAlphChar(string value)
455        {
456            int length = value.Length;
457            for (int i = 0; i < length; i++)
458            {
459                if (!settings.SubstitutionMatrix.Contains(value[i]))
460                {
461                    value = value.Remove(i, 1);
462                    i--;
463                    length--;
464                }
465            }
466            return value;
467        }
468
469        /// <summary>
470        /// Get position of the transposiotion password characters
471        /// </summary>
472        /// <param name="transPass"></param>
473        /// <returns></returns>
474        private int[] getOrder(string transPass)
475        {
476            int[] key = new int[transPass.Length];
477            for (int i = 0; i < transPass.Length; i++)
478            {
479                key[i] = settings.SubstitutionMatrix.IndexOf(transPass[i]);
480            }
481
482            int[] m_P = new int[key.Length];
483            int[] m_IP = new int[key.Length];
484
485            for (int idx1 = 0; idx1 < key.Length; idx1++)
486            {
487                m_P[idx1] = 0;
488                for (int idx2 = 0; idx2 < key.Length; idx2++)
489                {
490                    if (idx1 != idx2)
491                    {
492                        if (key[idx1] > key[idx2])
493                        {
494                            m_P[idx1]++;
495                        }
496                        else if ((key[idx1] == key[idx2]) & (idx2 < idx1))
497                        {
498                            m_P[idx1]++;
499                        }
500                    }
501                }
502            }
503            for (int idx = 0; idx < key.Length; idx++)
504            {
505                m_IP[m_P[idx]] = idx;
506            }
507            return m_IP;
508        }
509
510        #region IPlugin Members
511
512        public void Dispose()
513        {
514            foreach (CryptoolStream stream in listCryptoolStreamsOut)
515            {
516                stream.Close();
517            }
518            listCryptoolStreamsOut.Clear();
519        }
520
521        public bool HasChanges
522        {
523            get { return settings.HasChanges; }
524            set { settings.HasChanges = value; }
525        }
526
527        public void Execute()
528        {
529            switch (settings.Action)
530            {
531                case 0:
532                    Encrypt();
533                    break;
534                case 1:
535                    Decrypt();
536                    break;
537                default:
538                    break;
539            }
540        }
541
542        public void Initialize()
543        {
544           
545        }
546
547#pragma warning disable 67
548                                public event StatusChangedEventHandler OnPluginStatusChanged;
549                                public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
550                                public event PluginProgressChangedEventHandler OnPluginProgressChanged;
551#pragma warning restore
552
553        public void Pause()
554        {
555           
556        }
557
558        public void PostExecution()
559        {
560            Dispose();
561        }
562
563        public void PreExecution()
564        {
565            Dispose();
566        }
567
568        public System.Windows.Controls.UserControl Presentation
569        {
570            get { return null; }
571        }
572
573        public System.Windows.Controls.UserControl QuickWatchPresentation
574        {
575            get { return null; }
576        }
577
578        public void Stop()
579        {
580           
581        }
582
583        #endregion
584
585        #region INotifyPropertyChanged Members
586
587        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
588
589        public void OnPropertyChanged(string name)
590        {
591            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
592        }
593
594        #endregion
595
596        private void ADFGVX_LogMessage(string msg, NotificationLevel loglevel)
597        {
598            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(msg, this, loglevel));
599        }
600    }
601
602   
603}
Note: See TracBrowser for help on using the repository browser.