source: trunk/CrypPlugins/VigenereAnalyser/VigenereAnalyser.cs @ 2380

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

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

File size: 31.6 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Linq;
5using System.Text;
6using Cryptool.PluginBase;
7using Cryptool.PluginBase.Analysis;
8using Cryptool.PluginBase.IO;
9using System.ComponentModel;
10using System.Windows.Documents;
11using Cryptool.PluginBase.Miscellaneous;
12using System.Windows.Controls;
13using System.Windows.Threading;
14using System.Threading;
15
16namespace Cryptool.VigenereAnalyser
17{
18    [Author("Danail Vazov", "vazov@cryptool.org", "Uni Duisburg", "http://www.uni-duisburg-essen.de")]
19    [PluginInfo(false,
20    "Vigenere Analyser",
21    "Analyses a plain text encrypted using the Vigenere cipher. Output is the keyword of the Vigenere cipher", "",
22    "VigenereAnalyser/icon.png")]
23
24    public class VigenereAnalyser:IStatistic
25    {
26        public string cipherText;
27        public double sequenceIC;
28        public int IC_keyLength;
29        public int shiftKey = 0;
30        private double[] elf;
31        private double eic;
32        private VAPresentation vaPresentation;
33        private char[] validchars = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; //Sets alphabet of valid characters
34        private string keywordOutput;
35        private string frequencyOutput="";
36        private string stringOutput = "";
37        private string stringInput;
38        private double friedmanInput;
39        private int [] kasiskiInput;
40        private string frequencyStats;
41        private string[] vigToCaes;
42        private int v=0;
43        private int probableKeylength = 0;
44        private char FrequentChar = 'E';
45        public List <int> keys;
46        public List<string> fStats=new List<string>();
47        public class Stats
48        {
49                public char letter;
50                public int absoluteFrequency;
51                public double relativeFrequency;
52                public Stats(char letter, int absoluteFrequency, double relativeFrequency)
53                {
54                  this.letter = letter;
55                  this.absoluteFrequency=absoluteFrequency;
56                  this.relativeFrequency = relativeFrequency;
57                }
58           
59            }
60       
61
62        #region Private methods
63       
64        private void ShowStatusBarMessage(string message, NotificationLevel logLevel)
65        {
66            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
67        }
68
69        private void ShowProgress(double value, double max)
70        {
71            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
72        }
73        #endregion
74
75        #region Custom methods
76
77        private List<int> CaesarAnalysis(string text)
78        {
79            var Dic = new Dictionary<char, int>();
80
81            if (!string.IsNullOrEmpty(text))
82            {
83                foreach (var s in text.Split(new[] { "\r\n" }, StringSplitOptions.None))
84                {
85                    if (!string.IsNullOrEmpty(s))
86                    {
87                        string[] tmpArr = s.Split(new[] { ':' });
88                        if (tmpArr.Length > 1)
89                        {
90
91                            char c = tmpArr[0][0];
92                            int Count;
93                            int.TryParse(tmpArr[1], out Count);
94                            if (!Dic.ContainsKey(c))
95                                Dic.Add(c, 0);
96                            Dic[c] += Count;
97                        }
98                    }
99                }
100                var items = (from k in Dic.Keys
101                             orderby Dic[k] descending
102                             select k);
103
104                keys = new List<int>();
105                foreach (var c in items)
106                {
107                    int tmp = c - FrequentChar;
108                    int temp = 26 + tmp;
109                    if (tmp < 0)
110                        keys.Add(temp);
111                    if (tmp > 0)
112                        keys.Add(tmp);
113                    if (tmp == 0)
114                        keys.Add(tmp);
115                }
116                return keys;
117            }
118            return new List<int>();
119        }
120        private int leastSquares(string text)
121        {   
122            text=text.Replace(Environment.NewLine, ":");
123            char [] delimiter = {':'};
124            string[] splitStats = text.Split(delimiter);
125            List<Stats> freqStats = new List<Stats>();
126            for (int i = 0; i <splitStats.Length - 1; i = i + 3)
127            {
128                freqStats.Add(new Stats(System.Convert.ToChar(splitStats[i]), System.Convert.ToInt32(splitStats[i + 1]), System.Convert.ToDouble(splitStats[i + 2]))) ;
129            }
130            int textLength=0;
131            List<double> observedFrequencies = new List<double>();
132            freqStats.ForEach(delegate(Stats s)
133            {
134                textLength += s.absoluteFrequency;
135            });
136            double[] expectedFrequencies = new double[elf.Length];
137            for (int g = 0; g <= elf.Length - 1;g++ )
138            {
139                expectedFrequencies[g] = elf[g]/100;
140            }
141            if (freqStats.Count != elf.Length)
142            {
143                char[] check = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
144                int l = 0;
145                int c = 0;
146
147                for (int t = 0; t <= check.Length - 1; t++)
148                {
149
150                    if (c <= freqStats.Count - 1)
151                    {
152
153                        Stats r = freqStats.ElementAt(c);
154                        if (check[t] == r.letter)
155                        {
156                            observedFrequencies.Add(r.relativeFrequency);
157                            l++;
158                            c++;
159                        }
160                        else
161                        {
162                            observedFrequencies.Add(0.00000);
163                            l--;
164                        }
165                    }
166                    else
167                    {
168                        observedFrequencies.Add(0.00000);
169                    }
170                }
171            }
172            else 
173            {
174                freqStats.ForEach(delegate(Stats s)
175                {
176                    observedFrequencies.Add(s.relativeFrequency);
177                });
178            }
179            double [] chiStats = new double[26];
180            for (int y = 0; y <=25 ;y++)
181            {
182                double chi = 0;
183                double chiS = 0;
184                for (int j = 0; j<=observedFrequencies.Count - 1; j++)
185                {
186                    int n = (y + j)%26;
187                    chi = expectedFrequencies[j]-observedFrequencies[n];
188                    chiS = (Math.Pow(chi, 2));
189                    chiStats[y] += chiS;
190                }
191               
192            }
193            shiftKey = 0;
194            int b=0;
195            foreach (double k in chiStats)
196            {
197                 if (chiStats[b]-chiStats[shiftKey]<0.002 )
198                 {
199                     shiftKey = b;
200                 }
201                 b++;
202            }
203            /*if (shiftKey > 19)
204            {
205                shiftKey++;
206            }*/
207            return shiftKey;
208        }
209
210        private double seqIC (int d)
211        {
212            int j=0;
213            char[] cText = cipherText.ToCharArray();
214            int n = cText.Length;
215            int[] freq = new int[26];
216            int length = 0;
217            double[] IC = new double[d];
218            double sum,sum1;
219            char checkChar = 'a';
220            for (int i = 0; i < d; i++)
221            {
222                for(int y=0;y<=freq.Length-1;y++)
223                {
224                    freq[y] = 0;
225                }
226                j=1;
227                int index=d*(j-1)+i;
228                do
229                {
230                    freq[cText[index]-checkChar]+=1;
231                    j++;
232                }
233                while((index=d*(j-1)+i)<n);
234                length = j-1;
235                sum = 0.0;
236                for (int f = 0; f < 26; f++)
237                {
238                    sum += freq[f] * (freq[f] - 1);
239                }
240                IC[i] = sum / (length*(length-1));
241               
242            }
243            sum1 = 0.0;
244            for (int k = 0; k < d; k++)
245            {
246               sum1 += Math.Pow((IC[k] - eic), 2);
247            }
248            return sequenceIC = Math.Sqrt((sum1 / d));
249           
250           
251        }
252        private int sieveIC()
253        {
254            int max_keyLength = settings.Max_Keylength;
255            if (cipherText.Length < max_keyLength)
256            {
257                ShowStatusBarMessage("The maximum keylength to be analysed is bigger than the length of the ciphertext. Adjusting maximum keylength to be equal to the ciphertext length, in order to avoid errors.", NotificationLevel.Info);
258                max_keyLength = cipherText.Length - 1;
259            }
260            double check;
261            double max_diff = 0.002;
262            IC_keyLength = 1;
263            double min_keyLength=seqIC(1);
264            for (int i = 2; i <max_keyLength; i++)
265            {
266                 check = seqIC(i);
267                 if (min_keyLength-check>max_diff)
268                 {
269                     IC_keyLength = i;
270                     min_keyLength = check;
271                 }
272            }
273            return IC_keyLength;
274        }
275        #endregion
276
277        #region Properties (Inputs/Outputs)
278
279        [PropertyInfo(Direction.InputData, "Double precission floating point value.", "Keylength as proposed by the Friedman Test.", "", true, true, QuickWatchFormat.Text, null)]
280        public double FriedmanInput
281        {
282            get { return friedmanInput; }
283            set
284            {
285                if (value != friedmanInput)
286                {
287                    friedmanInput = value;
288                    OnPropertyChanged("FriedmanInput");
289                   
290                }
291            }
292        }
293        [PropertyInfo(Direction.InputData, "Text Input.", "Cipher text encrypted with the Vigenere cipher.", "", true, true, QuickWatchFormat.Text, null)]
294        public string StringInput
295        {
296            get
297            {
298                return stringInput;
299            }
300            set { stringInput = value; OnPropertyChanged("StringInput"); }
301        }
302        [PropertyInfo(Direction.InputData, "Integer Array.", "The Array cointains keylengths as proposed by the Kasiski Test.", "", false, true, QuickWatchFormat.Text, null)]
303        public int[] KasiskiInput
304        {
305            get { return kasiskiInput; }
306            set
307            {
308                if (value != kasiskiInput)
309                {
310                    kasiskiInput = value;
311                    OnPropertyChanged("KasiskiInput");
312                   
313                }
314            }
315        }
316        [PropertyInfo(Direction.OutputData, "Integer Array.", "Keyword represented as an integer Array.", "", false, true, QuickWatchFormat.Text, null)]
317        public string KeywordOutput
318        {
319            get { return keywordOutput; }
320            set
321            {
322                if (value != keywordOutput)
323                {
324                    keywordOutput = value;
325                    OnPropertyChanged("KeywordOutput");
326
327                }
328            }
329        }
330        [PropertyInfo(Direction.InputData, "String", "Please only connect to the text output of the Frequency Test.", "", true, true, QuickWatchFormat.Text, null)]
331        public string FrequencyStats
332        {
333            get { return frequencyStats; }
334            set
335            {
336                if (value != frequencyStats)
337                {
338                    frequencyStats = value;
339                    OnPropertyChanged("FrequencyStats");
340                    //inputChange = true;
341                    v++;
342                }
343            }
344        }
345
346        [PropertyInfo(Direction.OutputData, "String", "The cipher text divided into columns. Number of columns (strings) equals keylength.", "", false, false, QuickWatchFormat.Text, null)]
347        public string FrequencyOutput
348        {
349            get { return frequencyOutput; }
350            set
351            {
352                frequencyOutput = value;
353                OnPropertyChanged("FrequencyOutput");
354               
355
356            }
357        }
358        [PropertyInfo(Direction.OutputData, "Text output", " Keyword of the cipher which was used to encrypt the input text. ", "", false, false, QuickWatchFormat.Text, null)]
359        public string StringOutput
360        {
361            get { return stringOutput; }
362            set
363            {
364                stringOutput = value;
365                OnPropertyChanged("StringOutput");
366               
367
368            }
369        }
370       
371        #endregion
372
373
374        #region IPlugin Members
375        private VigenereAnalyserSettings settings;
376        public ISettings Settings
377        {
378            get { return settings; }
379            set { settings = (VigenereAnalyserSettings)value; }
380
381        }
382        public UserControl Presentation { get; private set; }
383
384        public UserControl QuickWatchPresentation
385        {
386            get { return Presentation; }
387        }
388        public VigenereAnalyser() 
389        {
390            settings = new VigenereAnalyserSettings();
391            vaPresentation = new VAPresentation();
392
393            Presentation = vaPresentation;
394        }
395        void textBoxInputText_TextChanged(object sender, TextChangedEventArgs e)
396        {
397            settings.Text = vaPresentation.textBoxInputText.Text;
398        }
399        public void Initialize()
400        {
401            if (vaPresentation.textBoxInputText != null)
402            {
403                vaPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
404                {
405                    vaPresentation.textBoxInputText.Text = settings.Text;
406                }, null);
407            }
408
409            vaPresentation.textBoxInputText.TextChanged += textBoxInputText_TextChanged;
410        }
411        public void Dispose()
412        {
413            vaPresentation.textBoxInputText.TextChanged -= textBoxInputText_TextChanged;
414        }
415
416        public void PreExecution()
417        {
418            keywordOutput = null;
419            fStats.Clear();
420            frequencyStats = null;
421            frequencyOutput = null;
422            vigToCaes = null;
423            probableKeylength = 0;
424            keys = null;
425           
426
427        }
428        public void Execute()
429        {
430           if (kasiskiInput != null)
431           {
432                //take care of settings first...
433               switch (settings.EIC)
434               {
435                   case 1: eic=0.0766; break;
436                   case 2: eic = 0.0746; break;
437                   case 3: eic=0.0775; break;
438                   case 4: eic =0.0775; break;
439                   case 5: eic = 0.074528; break;
440                   default: eic = 0.0665; break;
441               }
442               switch (settings.ELF)
443               {
444                   case 1: elf = new double[26] { 6.51, 1.89, 3.06, 5.08, 17.4, 1.66, 3.01, 4.76, 7.55, 0.27, 1.21, 3.44, 2.53, 9.78, 2.51, 0.79, 0.02, 7, 7.27, 6.15, 4.35, 0.67, 1.89, 0.03, 0.04, 1.13 }; break;
445                   case 2: elf = new double[26] { 7.636, 0.901, 3.26, 3.669, 14.715, 1.066, 0.866, 0.737, 7.529, 0.545, 0.049, 5.456, 2.968, 7.095, 5.378, 3.021, 1.362, 6.553, 7.948, 7.244, 6.311, 1.628, 0.114, 0.387, 0.308, 0.136 }; break;
446                   case 3: elf = new double[26] { 8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074 }; break;
447                   case 4: elf = new double[26] { 8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074 }; break;
448                   case 5: elf = new double[26] { 8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074 }; break;
449                   default: elf = new double[26] { 8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074 }; break;
450               }
451               
452                if (vigToCaes==null)
453                {   
454                    double friedmanKey = friedmanInput;
455                    int[] kasiskiFactors = kasiskiInput;
456                    string workString = stringInput;
457                    //Convert the cipher text into a format suitable for analysing i.e. remove all non-plaintext characters. //TO DO alphabet input...
458                   
459                    string strValidChars = new string(validchars);
460                    StringBuilder workstring1 = new StringBuilder();
461                    char[] workStringArray = workString.ToCharArray();
462                    foreach (char c in workStringArray)
463                    {
464                        if (strValidChars.IndexOf(c) >= 0) //If a char from the workString is valid, it is  appended to a newly built workstring1
465                        {
466                            workstring1.Append(c);
467                        }
468                    }
469
470                    cipherText = workstring1.ToString(); // Now copy workstring1 to workstring2. Needed because workstring1 can not be altered once its built
471                    cipherText = cipherText.ToLower();
472                    if (settings.internalKeyLengthAnalysis == 1) 
473                    {
474                        sieveIC();
475                        probableKeylength = IC_keyLength;
476
477                    }
478                    if (settings.internalKeyLengthAnalysis == 0)
479                    {
480                        //Start analysing the keylenghts proposed by the Friedman and Kasiski tests, and find the most propbable keylength.
481                        int[] primes = new int[] { 5  ,    7  ,   11   ,  13   ,  17  ,   19 ,    23  ,   29 ,
482                31   ,  37  ,   41 ,    43  ,   47  ,   53}; //Basic Array of prime numbers...replace with a primes generator or some sieve algorithm???
483                        int biggestSoFar = 0;
484                        int biggestSoFarIndex = 0;
485                        int z = 0;
486                        //Now we initialize an empty jagged array in which plausable keylengths with their respective probabilities will be stored
487                        int[][] proposedKeylengths = 
488                {
489                 new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
490                 new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0}
491   
492                };
493                        //Fill up the array
494                        for (int j = kasiskiFactors.Length - 1; j >= 0; j--)
495                        {
496                            if (kasiskiFactors[j] > biggestSoFar)
497                            {
498                                biggestSoFar = kasiskiFactors[j];
499                                biggestSoFarIndex = j;
500                                proposedKeylengths[0][z] = j;
501                                proposedKeylengths[1][z] = kasiskiFactors[j];
502                                z++;
503
504                            }
505                        }
506                        //The resulting array contains some plausible keylengths and some not so plausible keylengths.
507                        //The variable "biggestSoFarIndex" contains the most common factor, hence most plausible keylength. Problem - biggestSoFarIndex is 2...
508
509                        //After the most common factor is found check if this factor is a prime number. If yes - job done, this is indeed the key length.
510                        foreach (int s in primes)
511                        {
512                            if (s == biggestSoFarIndex)
513                            {
514                                probableKeylength = biggestSoFarIndex;
515                                goto Massages;
516                            }
517                        }
518                        //In case the most common factor is not prime...well tough luck. We'll have to make some assumptions...
519                        //First of all let's sort out unprobable keylengths.
520                        double check1 = 0.55 * biggestSoFar;
521                        int check = Convert.ToInt32(check1);
522                        for (int r = 0; r <= proposedKeylengths[0].Length - 1; r++)
523                        {
524                            if (proposedKeylengths[1][r] < check)
525                            {
526                                proposedKeylengths[0][r] = 0;
527                                proposedKeylengths[1][r] = 0;
528                            }
529
530                        }
531                        //The unprobalbe keylengths are now replaced with zeroes.
532                        //Get rid of the zeroes...
533                        ArrayList factors = new ArrayList();
534                        ArrayList count = new ArrayList();
535                        for (int d = 0; d <= proposedKeylengths[0].Length - 1; d++)
536                        {
537                            if (proposedKeylengths[0][d] != 0)
538                            {
539                                factors.Add(proposedKeylengths[0][d]);
540                                count.Add(proposedKeylengths[1][d]);
541                            }
542                        }
543                        //The dynamic arrays "factors" and "count" now contain only the most prorbale keylengths and their respective probability.
544                        //For ease of access convert the dynamic arrays in to normal ones
545                        int[] factors1 = (int[])factors.ToArray(typeof(int));
546                        int[] count1 = (int[])count.ToArray(typeof(int));
547                        int a = factors1.Length;
548                        //Now check the difference in probability between the most common and most uncommon factors
549                        double smallestCount = count1[0]; //c# does not implicitly convert between int and double, hence two new variables are needed
550                        double biggestCount = count1[a - 1];
551                        double controlValue = smallestCount / biggestCount;
552                        //Now can make some assumptions...
553                        if (a > 3)
554                        {
555                            if (factors1[0] % factors1[a - 1] == 0 && factors1[0] % factors1[a - 2] == 0 && factors1[0] % factors1[a - 3] == 0 && controlValue > 0.65)
556                            {
557                                probableKeylength = factors1[0];
558                            }
559                            else { probableKeylength = factors1[1]; }
560                        }
561                        if (a == 3)
562                        {
563                            if (factors1[0] % factors1[a - 1] == 0 && factors1[0] % factors1[a - 2] == 0 && controlValue > 0.75)
564                            {
565                                probableKeylength = factors1[0];
566                            }
567                            if (factors1[0] % factors1[a - 2] == 0 && factors1[0] % factors1[a - 1] != 0 && controlValue > 0.6)
568                            {
569                                probableKeylength = factors1[0];
570                            }
571
572                        }
573                        if (a == 2)
574                        {
575                            if (factors1[0] % factors1[a - 1] == 0 && controlValue > 0.75)
576                            {
577                                probableKeylength = factors1[0];
578                            }
579
580                        }
581                        if (a == 1)
582                        {
583                            probableKeylength = factors1[0];
584                        }
585                    //Now that we've made some rudimentary decission making, let's check if it has payed off...
586                    Massages:
587                        if (Math.Abs(probableKeylength - friedmanKey) < 1)
588                        {
589                            ShowStatusBarMessage("Analysed proposed keylengths. The derived keylength is the correct value." + "" + "Derived keylength is:" + probableKeylength.ToString(), NotificationLevel.Info);
590                        }
591                        if (Math.Abs(probableKeylength - friedmanKey) > 1 && Math.Abs(probableKeylength - friedmanKey) < 2)
592                        {
593                            ShowStatusBarMessage("Analysed proposed keylengths. The derived keylength is probably the correct value" + "" + "Derived keylength is:" + probableKeylength.ToString(), NotificationLevel.Info);
594                        }
595                        if (Math.Abs(probableKeylength - friedmanKey) > 2 && Math.Abs(probableKeylength - friedmanKey) < 3)
596                        {
597                            ShowStatusBarMessage("Analysed proposed keylengths. The derived keylength may not be the correct value." + "" + "Derived keylength is:" + probableKeylength.ToString(), NotificationLevel.Info);
598                        }
599                        if (Math.Abs(probableKeylength - friedmanKey) > 3)
600                        {
601                            ShowStatusBarMessage("Analysed proposed keylengths. Friedman or Kasiski test provided a value that was wrong. A manual analysis may be needed to confirm the derived keylength." + "" + "Derived keylength is:" + probableKeylength.ToString(), NotificationLevel.Info);
602                        }
603                        factors1 = null;
604                    }
605                    //Now we have a good idea of the keylength used to encrypt the ciphertext recived on the stringInput.
606                    //Let's start with the analysis of the Vigenere cipher proper.
607                    //First we need to divide the cipher text into columns. The number of columns must be equal to the probableKeylength.
608                    //Create an array of strings. Just a container for the columns.
609                    char[] cipherTextChars = cipherText.ToCharArray();
610                    int l = 0;
611                    //Now we fill up the vigenereToCeasar array with strings.
612                    string[] vigenereToCaesar = new string[probableKeylength];
613                    for (int b = 0; b <= probableKeylength - 1; b++)
614                    {
615                        StringBuilder tempstring = new StringBuilder();
616                        for (l = b; l <= cipherTextChars.Length - 1; l = l + probableKeylength)
617                        {
618                            tempstring.Append(cipherTextChars[l]);
619                        }
620                        vigenereToCaesar[b] = tempstring.ToString();
621                        tempstring = null;
622                    }
623                    //After the outer loop is executed probableKeylength-times every element of vigenereToCaesar contains a string.
624                    //Each of those strings should be alligned to the same keyletter of the Vigenere key which was used to encrypt the analysed text.
625                    //Hence each string is encrypted using the Caeser cipher, and a Frequency Test for each string should give us a good idea of what the shift key is for the respective string.
626                    //Furthermore the vigenerToCaesar is allready sorted in such a way that the index of each element coresponds to the position of its respective shift key in the whole key.
627                    vigToCaes = vigenereToCaesar;
628                   
629                   
630                }
631                if (vigToCaes != null)
632                {
633                    if (v <= probableKeylength - 1)
634                    {
635                        frequencyOutput = vigToCaes[v];
636                        OnPropertyChanged("FrequencyOutput");
637                    }
638                    if (frequencyStats != null && frequencyStats != string.Empty&&!fStats.Contains(frequencyStats))
639                    {
640                        fStats.Add(frequencyStats);
641                    }
642                }
643                if (v == probableKeylength)
644                {
645                    int[] probableKeyword = new int[probableKeylength];
646                    if (settings.columnAnalysis == 0)
647                    {
648                        List<List<int>> keyList = new List<List<int>>();
649                        foreach (string c in fStats)
650                        {
651                            if (c != null)
652                            {
653                                CaesarAnalysis(c);
654                                keyList.Add(keys);
655                            }
656                        }
657                        for (int f = 0; f <= probableKeylength - 1; f++)
658                        {
659                            int[] tempKey = keyList.ElementAt(f).ToArray();
660                            probableKeyword[f]=tempKey[0];
661                            tempKey = null;
662                        }
663                        keyList = null;
664
665                    }
666                    if (settings.columnAnalysis == 1)
667                    {
668                        List<int> chiList = new List<int>();
669                        foreach (string c in fStats)
670                        {
671                            if (c != null)
672                            {
673                                leastSquares(c);
674                                chiList.Add(shiftKey);
675                            }
676                        }
677                        for (int f = 0; f <= probableKeylength - 1; f++)
678                        {
679                           
680                            probableKeyword[f] = chiList.ElementAt(f);
681                        }
682                    }
683                    StringBuilder keywordstring = new StringBuilder();
684                    foreach(int r in probableKeyword)
685                    {
686                        keywordstring.Append(validchars[r]);
687                    }
688                    keywordOutput = keywordstring.ToString();
689                    OnPropertyChanged("KeywordOutput");
690                }
691            }
692        }
693
694       
695
696        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
697
698        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
699
700        public event StatusChangedEventHandler OnPluginStatusChanged;
701
702        public void Pause()
703        {
704            //throw new NotImplementedException();
705        }
706
707        public void PostExecution()
708        {   
709            frequencyStats = null;
710            kasiskiInput = null;
711            v = 0;
712        }
713        public void Stop()
714        {
715            //throw new NotImplementedException();
716        }
717
718        #endregion
719
720        #region INotifyPropertyChanged Members
721
722        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
723
724        protected void OnPropertyChanged(string name)
725        {
726            if (PropertyChanged != null)
727            {
728                PropertyChanged(this, new PropertyChangedEventArgs(name));
729            }
730        }
731
732        #endregion
733    }
734}
Note: See TracBrowser for help on using the repository browser.