source: trunk/CrypPlugins/MonoalphabeticAnalysis/MonoalphabeticAnalysis.cs @ 332

Last change on this file since 332 was 332, checked in by angelov, 13 years ago

Breaks Substitution Cypher. A bit Slow. Could be fixed. Also Buggy. But it works.

File size: 16.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.IO;
6using Cryptool.PluginBase;
7using Cryptool.PluginBase.Analysis;
8using System.ComponentModel;
9using System.Windows.Controls;
10using System.Windows.Documents;
11using System.Windows.Markup;
12using Cryptool.PluginBase.IO;
13using System.Collections.ObjectModel;
14using Cryptool.MonoalphabeticAnalysis;
15using System.Collections;
16using System.Threading;
17using System.Windows;
18using System.Windows.Threading;
19using System.Runtime.CompilerServices;
20using Cryptool.PluginBase.Miscellaneous;
21
22using System.Runtime.Remoting.Contexts;
23
24
25namespace Cryptool.MonoalphabeticAnalysis
26{
27    [Author("Georgi Angelov", "angelov@cryptool.org", "Uni Duisburg", "http://www.uni-duisburg-essen.de")]
28    [PluginInfo(false,
29    "MonoalphabeticAnalysis",
30    "Proposes Alphabet for the substitution cypher.",
31    "",
32    "MonoalphabeticAnalysis/icon.png")]
33
34
35
36    public partial class MonoalphabeticAnalysis : IStatistic
37    {
38        private string stringOutput = "";
39        private string statisticTextFrequencyInput_Monograms="";
40        private string statisticTextFrequencyInput_Digrams="";
41        private string cypherTextFrequencyInput_Monograms="";
42        private string decypherAttempt_Digrams=""; //After the initial alphabet is proposed and decrypt from substitution plug-in is generated, the result is analysed with Frequencytest concerning digrams and fed back to MonoalphabeticAnalysis as input.
43        public string GoodAlphabet = null;
44        public string NextAlphabet = null;
45        private double alphabetGoodnes = 0;
46        public int AlphabetCounterA = 1;
47        public int AlphabetcounterB = 1;
48       
49
50
51
52        #region Properties (Inputs/Outputs)
53
54        [PropertyInfo(Direction.Input, "StatisticTextFrequencyInput_Monograms", "StatisticTextFrequencyInput_Monograms", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
55        public string StatisticTextFrequencyInput_Monograms
56        {
57            get
58            {
59                return statisticTextFrequencyInput_Monograms;
60            }
61            set { statisticTextFrequencyInput_Monograms = value; OnPropertyChanged("StatisticTextFrequencyInput_Monograms"); }
62        }
63
64
65        [PropertyInfo(Direction.Input, "StatisticTextFrequencyInput_Digrams", "StatisticTextFrequencyInput_Digrams", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
66        public string StatisticTextFrequencyInput_Digrams
67        {
68            get
69            {
70                return statisticTextFrequencyInput_Digrams;
71            }
72            set { statisticTextFrequencyInput_Digrams = value; OnPropertyChanged("StatisticTextFrequencyInput_Digrams"); }
73        }
74
75
76        [PropertyInfo(Direction.Input, "CypherTextFrequencyInput_Monograms", "CypherTextFrequencyInput_Monograms", "", true, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
77        public string CypherTextFrequencyInput_Monograms
78        {
79            get
80            {
81                return cypherTextFrequencyInput_Monograms;
82            }
83            set { cypherTextFrequencyInput_Monograms = value; OnPropertyChanged("CypherTextFrequencyInput_Monograms"); }
84        }
85
86        [PropertyInfo(Direction.Input, "DecypherAttempt_Digrams", "DecypherAttempt_Digrams", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
87        public string DecypherAttempt_Digrams
88        {
89            get
90            {
91                return decypherAttempt_Digrams;
92            }
93            set { decypherAttempt_Digrams = value; OnPropertyChanged("DecypherAttempt_Digrams"); }
94        }
95
96
97        [PropertyInfo(Direction.Output, "String output", "Proposal Alphabets", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
98        public string StringOutput
99        {
100            get { return stringOutput; }
101            set
102            {
103                StringOutput = value;
104                OnPropertyChanged("StringOutput");
105
106            }
107        }
108
109
110
111        [PropertyInfo(Direction.Output, "Alphabet goodness", "Alphabet goodness", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
112        public string AlphabetGoodness
113        {
114            get { return alphabetGoodnes.ToString(); }
115            set
116            {
117                StringOutput = value;
118                OnPropertyChanged("Alphabetgoodness");
119
120            }
121        }
122       
123       
124       
125       
126        #endregion
127
128
129
130
131        #region IPlugin Members
132
133        public event StatusChangedEventHandler OnPluginStatusChanged;
134
135        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
136
137        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
138
139        private MonoalphabeticAnalysisSettings settings;
140        public ISettings Settings
141        {
142            get { return settings; }
143            set { settings = (MonoalphabeticAnalysisSettings)value; }
144        }
145        // private FrequencyTestPresentation presentation;
146        public MonoalphabeticAnalysis()
147        {
148            settings = new MonoalphabeticAnalysisSettings();
149            // presentation = new FrequencyTestPresentation(this);
150            // Presentation = presentation;
151            //  QuickWatchPresentation = presentation;
152        }
153        public UserControl Presentation { get; private set; }
154
155
156        public UserControl QuickWatchPresentation { get; private set; }
157
158        public void PreExecution()
159        {
160            //throw new NotImplementedException();
161        }
162       
163       
164       
165        //////////////
166        //EXECUTE!!!//
167        //////////////
168     
169        public void Execute()
170        {
171           
172
173            if (cypherTextFrequencyInput_Monograms != "")
174            {
175                   //if Optional Statistical input not used -> use variables from pre-analysed Text (James Clavel's Shogun) 
176                 if (statisticTextFrequencyInput_Monograms == "") statisticTextFrequencyInput_Monograms = ShogunStatistics.ShogunMonograms;
177
178
179                 if (GoodAlphabet == null)
180                 {
181                    //decypherAttempt_Digrams equals null means initial alphabet should be generated
182                    string alphabet = "";
183                    ArrayList mapping1 = InitialMapping(cypherTextFrequencyInput_Monograms, statisticTextFrequencyInput_Monograms);
184
185                    alphabet = AlphabetFromMapping(mapping1);
186
187                    GoodAlphabet = alphabet;
188                    stringOutput = alphabet;
189                    OnPropertyChanged("StringOutput");
190
191                 }
192
193
194
195                 if (GoodAlphabet != null && decypherAttempt_Digrams!="")
196                 {
197
198                     double goodness = ReturnAlphabetGoodness();
199                     if (alphabetGoodnes == 0) //secondpass
200                     { 
201                         alphabetGoodnes = goodness;
202                     } 
203                     if (alphabetGoodnes > goodness) //third pass and on if condition applies
204                     {
205                         GoodAlphabet = NextAlphabet;
206                         alphabetGoodnes = goodness;
207                     }
208
209                     string alphabet1 = GenerateNextAlphabet();
210                     NextAlphabet = alphabet1;
211                     stringOutput = NextAlphabet;
212                     OnPropertyChanged("StringOutput");
213
214
215
216
217                 }
218
219
220
221            }
222
223           
224           
225               
226
227        }
228
229
230
231        public void PostExecution()
232        {
233           
234            //throw new NotImplementedException();
235        }
236
237        public void Pause()
238        {
239            //throw new NotImplementedException();
240        }
241
242        public void Stop()
243        {
244            //statisticTextFrequencyInput_Monograms = "";
245            //OnPropertyChanged("StatisticTextFrequencyInput_Monograms");
246           // statisticTextFrequencyInput_Digrams = "";
247            //OnPropertyChanged("StatisticTextFrequencyInput_Digrams");
248           
249            //throw new NotImplementedException();
250        }
251
252        public void Initialize()
253        {
254            //throw new NotImplementedException();
255        }
256
257        public void Dispose()
258        {
259            //throw new NotImplementedException();
260        }
261
262
263        #endregion
264
265        #region INotifyPropertyChanged Members
266
267        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
268
269        protected void OnPropertyChanged(string name)
270        {
271            if (PropertyChanged != null)
272            {
273                PropertyChanged(this, new PropertyChangedEventArgs(name));
274            }
275        }
276
277        #endregion
278
279
280        #region CUSTOM METHODS
281
282
283
284
285        //RETURN SORTED LIST//  // The Method returns a sorted list from the FrequenscyTest string output.
286       
287        public ArrayList ReturnSortedList(string str,SortElements.SortElemetsBy sort_type)       
288        {
289           
290            str = str.Replace(Environment.NewLine, ":");
291
292            char[] splitter = { ':' };
293
294           
295            string[] splitFrequencies = str.Split(splitter);
296           
297
298            ArrayList sortingFrequencyList = new ArrayList();
299
300                       
301                for (int i = 0; i < splitFrequencies.Length - 1; i = i + 3)
302                {
303                    CollectionElement row = new CollectionElement(splitFrequencies[i], System.Convert.ToDouble(splitFrequencies[i + 2]),"");
304                    sortingFrequencyList.Add(row);
305                }
306             
307                                 
308
309            SortElements mySortingType = new SortElements(sort_type);
310            sortingFrequencyList.Sort(mySortingType);
311
312            return sortingFrequencyList;
313        }
314
315
316
317        //INITIAL MAPPING//
318
319       public ArrayList InitialMapping(string cyString, string statString)
320        {
321            if (statisticTextFrequencyInput_Monograms == "") statisticTextFrequencyInput_Monograms = ShogunStatistics.ShogunMonograms;
322            ArrayList cypherTextFrequencies = ReturnSortedList(cyString, SortElements.SortElemetsBy.byFrequency);
323            ArrayList statisticFrequencies = ReturnSortedList(statString, SortElements.SortElemetsBy.byFrequency);
324
325            ArrayList mappings = new ArrayList();
326
327            if (cypherTextFrequencies.Count == statisticFrequencies.Count)
328            {
329                for (int i = 0; i < cypherTextFrequencies.Count ; i++)
330                {
331                    CollectionElement a1 = (CollectionElement)cypherTextFrequencies[i];
332                    CollectionElement a2 = (CollectionElement)statisticFrequencies[i];
333                    double frequencyDifference = Math.Abs(a1.Frequency - a2.Frequency);
334                    CollectionElement row = new CollectionElement(a1.Caption, frequencyDifference, a2.Caption);
335                    mappings.Add(row);
336
337                }
338
339
340            }
341            SortElements mySortingType = new SortElements(SortElements.SortElemetsBy.byString);
342            mappings.Sort(mySortingType);
343
344            return mappings;
345        }
346
347
348
349
350        //ALPHABET FROM MAPPING//
351
352      public string AlphabetFromMapping(ArrayList mapping)
353        {
354            string alphabet = "";
355           
356            for (int i = 0; i < mapping.Count; i++)
357            {
358                CollectionElement a1 = (CollectionElement)mapping[i];
359                alphabet += a1.Mapping;
360            }
361
362            alphabet = alphabet.ToUpper();
363           
364            return alphabet;
365 
366        }
367
368     
369       //RETURN ALPHABET GOODNESS// Revision Needed!!!
370       
371      public double ReturnAlphabetGoodness() 
372      {
373          if (statisticTextFrequencyInput_Digrams == "") StatisticTextFrequencyInput_Digrams = ShogunStatistics.ShogunDigrams;//if Optional Statistical input not used -> use variables from pre-analysed Text (James Clavel's Shogun)
374
375          double[,] statisticDigramSquare = GetDigramFrequencySquare(StatisticTextFrequencyInput_Digrams);
376          double[,] decypherAttemptDigrams = GetDigramFrequencySquare(DecypherAttempt_Digrams);
377         // double[,] digramFrequencyDifferences = new double[GoodAlphabet.Length, GoodAlphabet.Length];
378          double goodness=new double();
379
380
381          for (int i = 0; i < GoodAlphabet.Length; i++)
382          {
383              for (int n = 0; n < GoodAlphabet.Length; n++)
384              {
385                  goodness +=Math.Abs( statisticDigramSquare[i, n] - decypherAttemptDigrams[i, n]);
386              }
387          }
388
389
390          return goodness;
391
392
393
394
395
396         /* ArrayList statisticList_Digrams = ReturnSortedList(statisticTextFrequencyInput_Digrams, SortElements.SortElemetsBy.byFrequency);
397
398          ArrayList decypherAttemptList_Digrams = ReturnSortedList(digramsFrequencies, SortElements.SortElemetsBy.byFrequency);
399
400          ArrayList digramFrequencyDifference = statisticList_Digrams;
401
402          for (int i = 0; i < decypherAttemptList_Digrams.Count; i++)
403          {
404              CollectionElement a1 = (CollectionElement)decypherAttemptList_Digrams[i];
405              string name1 = a1.Caption;
406
407              for (int n = 0; n < statisticList_Digrams.Count; n++)
408              {
409                  CollectionElement a2 = (CollectionElement)statisticList_Digrams[n];
410                  string name2 = a2.Caption;
411                  if (name1 == name2)
412                  {
413                      double difference = a2.Frequency - a1.Frequency;
414                      CollectionElement row = new CollectionElement(name1, difference, "");
415                      digramFrequencyDifference[n] = (Object)row;
416                  }
417                  if (name1[0] != name2[0]) break;
418              }
419
420
421          }
422          double sumOfDigramFrequencyDifferences = 0;
423
424          for (int m = 0; m < digramFrequencyDifference.Count; m++)
425          {
426              CollectionElement z = (CollectionElement)digramFrequencyDifference[m];
427              sumOfDigramFrequencyDifferences = sumOfDigramFrequencyDifferences + z.Frequency;
428          }
429
430          return Math.Abs(sumOfDigramFrequencyDifferences); */
431
432         /* decypherAttemptList_Digrams.Reverse();
433          statisticList_Digrams.Reverse();
434          int hits=0;
435
436          //CollectionElement[,] darray = new CollectionElement[GoodAlphabet.Length,GoodAlphabet.Length];
437          for (int i = 0; i < 30; i++)
438          {
439              CollectionElement a1 = (CollectionElement)decypherAttemptList_Digrams[i];
440              CollectionElement a2 = (CollectionElement)statisticList_Digrams[i];
441
442
443
444              if (a1.Caption == a2.Caption) hits += GoodAlphabet.Length * GoodAlphabet.Length - i * GoodAlphabet.Length;
445          }
446
447          return hits; */
448
449      }
450
451
452       //GENERATE NEXT ALPHABET//
453
454      public string GenerateNextAlphabet ()
455      {
456          //string alphabet = GoodAlphabet;
457         
458          if (AlphabetcounterB != GoodAlphabet.Length)  //TO DO:OTHER WAY TO REALY EXIT
459          {
460              char[] alphabet=GoodAlphabet.ToCharArray();
461
462              char holder = alphabet[AlphabetCounterA - 1];
463              alphabet[AlphabetCounterA - 1] = alphabet[AlphabetCounterA + AlphabetcounterB - 1];
464              alphabet[AlphabetCounterA + AlphabetcounterB - 1] = holder;
465              AlphabetCounterA++;
466              if (AlphabetCounterA + AlphabetcounterB > alphabet.Length)
467              {
468                  AlphabetCounterA = 1;
469                  AlphabetcounterB++;
470              }
471
472              string alphabet1=null;
473              alphabet1 = new string(alphabet);
474              return alphabet1;
475          }
476          else { return GoodAlphabet; } //TO DO: OTHER WAY TO REALY EXIT
477
478      }
479
480
481     
482       
483        //GET DIGRAM FREQUENCY SQUARE//
484
485     
486       
487      public double[,] GetDigramFrequencySquare(string digrams) 
488      {
489          double[,] digramFrequencySquare = new double[GoodAlphabet.Length, GoodAlphabet.Length];
490          char[] alphabetCharacters = GoodAlphabet.ToCharArray();
491          ArrayList digramfrequencyList = ReturnSortedList(digrams,SortElements.SortElemetsBy.byString);
492         
493         
494          Array.Sort(alphabetCharacters);
495
496          foreach (CollectionElement item in digramfrequencyList)
497          {
498              int firstLetterIndex = Array.IndexOf(alphabetCharacters,item.Caption.ToUpper()[0]);
499              int secondLetterIndex = Array.IndexOf(alphabetCharacters, item.Caption.ToUpper()[1]);
500              digramFrequencySquare[firstLetterIndex,secondLetterIndex]=item.Frequency;     
501             
502          }
503
504
505          return digramFrequencySquare;
506                 
507      }
508
509
510        #endregion CUSTOM METHODS
511
512    }
513
514       
515
516
517
518
519   
520
521   
522}
523
524
525
526
527
528
529
530
531
532
Note: See TracBrowser for help on using the repository browser.