Ignore:
Timestamp:
Jul 14, 2009, 11:09:21 AM (13 years ago)
Author:
Danail Vazov
Message:

Internal methods for analysing Caesar cipher added to the Vigener Analyser plug-in. A Setting for choosing the language to analyse was also added. This setting is used by the chi-square statistic in order to assert a Null hypothesis.

Changed the key word input of the Vigenere plug-in. Now it is just a normal string input.

Location:
trunk/CrypPlugins/VigenereAnalyser
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/VigenereAnalyser/VigenereAnalyser.cs

    r351 r388  
    2424    public class VigenereAnalyser:IStatistic
    2525    {
     26        public int shiftKey = 0;
     27        private double[] elf;
    2628        private VAPresentation vaPresentation;
    2729        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
    28         private int[] keywordOutput;
     30        private string keywordOutput;
    2931        private string frequencyOutput="";
    3032        private string stringOutput = "";
     
    3234        private double friedmanInput;
    3335        private int [] kasiskiInput;
    34         private int caesarKey;
     36        private string frequencyStats;
    3537        private string[] vigToCaes;
    3638        private int v=0;
    3739        private int probableKeylength = 0;
    38         int[] keys;
     40        private char FrequentChar = 'e';
     41        public List <int> keys;
     42        public List<string> fStats=new List<string>();
    3943        //private bool inputChange = false;
    40        
     44        public class Stats
     45        {
     46                public char letter;
     47                public int absoluteFrequency;
     48                public double relativeFrequency;
     49                public Stats(char letter, int absoluteFrequency, double relativeFrequency)
     50                {
     51                  this.letter = letter;
     52                  this.absoluteFrequency=absoluteFrequency;
     53                  this.relativeFrequency = relativeFrequency;
     54                }
     55           
     56            }
    4157       
    4258
     
    5369        }
    5470        #endregion
     71
     72        #region Custom methods
     73
     74        private List<int> CaesarAnalysis(string text)
     75        {
     76            var Dic = new Dictionary<char, int>();
     77
     78            if (!string.IsNullOrEmpty(text))
     79            {
     80                foreach (var s in text.Split(new[] { "\r\n" }, StringSplitOptions.None))
     81                {
     82                    if (!string.IsNullOrEmpty(s))
     83                    {
     84                        string[] tmpArr = s.Split(new[] { ':' });
     85                        if (tmpArr.Length > 1)
     86                        {
     87
     88                            char c = tmpArr[0][0];
     89                            int Count;
     90                            int.TryParse(tmpArr[1], out Count);
     91                            if (!Dic.ContainsKey(c))
     92                                Dic.Add(c, 0);
     93                            Dic[c] += Count;
     94                        }
     95                    }
     96                }
     97
     98                var items = (from k in Dic.Keys
     99                             orderby Dic[k] descending
     100                             select k);
     101
     102                keys = new List<int>();
     103                foreach (var c in items)
     104                {
     105                    int tmp = c - FrequentChar;
     106                    int temp = 26 + tmp;
     107                    if (tmp < 0)
     108                        keys.Add(temp);
     109                    if (tmp > 0)
     110                        keys.Add(tmp);
     111                    if (tmp == 0)
     112                        keys.Add(tmp);
     113
     114
     115                }
     116                return keys;
     117            }
     118            return new List<int>();
     119        }
     120        private int chiSquare(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<int> observedFrequencies = new List<int>();
     132            freqStats.ForEach(delegate(Stats s)
     133            {
     134                textLength += s.absoluteFrequency;
     135            });
     136            double[] expectedFrequencies = elf;
     137            if (freqStats.Count != elf.Length)
     138            {
     139                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' };
     140                int l = 0;
     141                for (int t = 0; t <= check.Length - 1;t++ )
     142                {
     143                       
     144                        if (l <= freqStats.Count - 1)
     145                        {
     146                            Stats r = freqStats.ElementAt(l);
     147                            if (check[t] == r.letter)
     148                            {
     149                                observedFrequencies.Add(r.absoluteFrequency);
     150                                l++;
     151                            }
     152                            else
     153                            {
     154                                observedFrequencies.Add(0);
     155                            }
     156                        }
     157                        else
     158                        {
     159                            observedFrequencies.Add(0);
     160                        }
     161                }
     162            }
     163            List<double> correctedFrequencies = new List<double>();
     164            foreach (double d in expectedFrequencies)
     165            {   
     166                correctedFrequencies.Add((d / 100) * textLength);
     167            }
     168            double [] eFrequencies = correctedFrequencies.ToArray();
     169            //int[] oFrequencies = observedFrequencies.ToArray();
     170            double [] chiStats = new double[26];
     171            foreach (int f in observedFrequencies)
     172            {
     173                double chi = 0;
     174                double chiS = 0;
     175                int g = observedFrequencies.IndexOf(f);
     176                for (int j = 0; j <= 25; j++)
     177                {
     178                    int n = g + j;
     179                    if (n == 25||n>25)
     180                    {
     181                        n = n - 25;
     182                    }
     183                    chi = observedFrequencies[n];
     184                    chiS = Math.Pow(chi, 2);
     185                    chiS = chiS / eFrequencies[g];
     186                    chiStats[j] += chiS;
     187                }
     188            }
     189           
     190            foreach (double k in chiStats)
     191            {   
     192                shiftKey=Array.IndexOf(chiStats , k);
     193                for (int l = Array.IndexOf(chiStats, k) + 1; l < chiStats.Length; l++)
     194                {
     195                    if (chiStats[l]<chiStats[shiftKey] )
     196                    {
     197                        shiftKey = l;
     198                    }
     199                }
     200               
     201            }
     202            return shiftKey;
     203
     204
     205        }
     206        #endregion
     207
    55208        #region Properties (Inputs/Outputs)
    56        
     209
    57210        [PropertyInfo(Direction.Input, "Double precission floating point value.", "Keylength as proposed by the Friedman Test.", "", true, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
    58211        public double FriedmanInput
     
    93246        }
    94247        [PropertyInfo(Direction.Output, "Integer Array.", "Keyword represented as an integer Array.", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
    95         public int[] KeywordOutput
     248        public string KeywordOutput
    96249        {
    97250            get { return keywordOutput; }
     
    107260        }
    108261        [PropertyInfo(Direction.Input, "String", "Please only connect to the text output of the Frequency Test.", "", true, true, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
    109         public int CaesarKey
    110         {
    111             get { return caesarKey; }
     262        public string FrequencyStats
     263        {
     264            get { return frequencyStats; }
    112265            set
    113266            {
    114                 if (value != caesarKey)
    115                 {
    116                     caesarKey = value;
    117                     OnPropertyChanged("CaesarKey");
     267                if (value != frequencyStats)
     268                {
     269                    frequencyStats = value;
     270                    OnPropertyChanged("FrequencyStats");
    118271                    //inputChange = true;
    119272                    v++;
     
    174327        void textBoxInputText_TextChanged(object sender, TextChangedEventArgs e)
    175328        {
    176             //this.NotifyUpdate();
     329            this.NotifyUpdate();
    177330            settings.HasChanges = true;
    178331           
    179332        }
     333        public void NotifyUpdate()
     334        {
     335            settings.Text = vaPresentation.textBoxInputText.Text;
     336        }
    180337        public void Initialize()
    181338        {
     
    196353        public void PreExecution()
    197354        {
    198            
    199             caesarKey = 0;
     355            keywordOutput = null;
     356            fStats.Clear();
     357            frequencyStats = null;
    200358            frequencyOutput = null;
    201359            vigToCaes = null;
    202360            probableKeylength = 0;
    203             //inputChange = false;
    204361            keys = null;
    205362           
     
    209366        {
    210367           if (kasiskiInput != null)
    211             {
     368           {
     369                //double [] elf;
     370                switch (settings.ELF)
     371                {
     372                   case 1: 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;
     373                   case 2: 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;
     374                   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;
     375                   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;
     376                   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;
     377                   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;
     378                }
    212379                if (vigToCaes==null)
    213                 {
     380                {   
    214381                    double friedmanKey = friedmanInput;
    215382                    int[] kasiskiFactors = kasiskiInput;
     
    312479                            probableKeylength = factors1[0];
    313480                        }
     481                        else { probableKeylength = factors1[1]; }
    314482                    }
    315483                    if (a == 3)
     
    378546                    //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.
    379547                    vigToCaes = vigenereToCaesar;
    380                     keys = new int[probableKeylength + 1];
    381548                    factors1 = null;
    382549                   
     
    384551                if (vigToCaes != null)
    385552                {
    386 
    387 
    388553                    if (v <= probableKeylength - 1)
    389554                    {
     
    391556                        OnPropertyChanged("FrequencyOutput");
    392557                    }
    393                     keys[v] = caesarKey;
    394 
    395 
    396 
    397                 }
    398                
    399               //After the loop on the workspace was executed probableKeylength-times the array keys contains the actual key in form of shift values.
    400                int []keyword=new int [keys.Length-1];
    401                int n = 0;
    402                if (v==probableKeylength)
    403                {
    404                    
    405                    for (int t = 1; t <= keys.Length - 1; t++)
    406                    {
    407                        keyword[n] = keys[t];
    408                        n++;
    409                    }
    410                    
    411                }
    412                if (keys.Length-1==n)
    413                {
    414                    keywordOutput = keyword;
    415                    OnPropertyChanged("KeywordOutput");
    416                    /*if ()
    417                    {
    418                        int k = 0;
    419                        int[] keyword1 = new int[settings.Text.Length];
    420                        foreach (char g in settings.Text)
    421                        {   for (int f =0;f<=validchars.Length-1;f++)
    422                        {
    423                            if (g == validchars[f])
    424                            {
    425                                keyword1[k] = f;
    426                                k++;
    427                            }
    428                         }
    429                        }
    430                        keywordOutput = keyword1;
    431                        OnPropertyChanged("KeywordOutput");
    432 
    433                    }*/
    434                }
    435                StringBuilder keywordstring = new StringBuilder();
    436                foreach (int r in keyword)
    437                {
    438                    keywordstring.Append(validchars[r]);
    439                }
    440 
    441                settings.Text = keywordstring.ToString();
    442                Initialize();
    443                string value = (string)this.vaPresentation.textBoxInputText.Dispatcher.Invoke(DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
    444                {
    445                    return vaPresentation.textBoxInputText.Text;
    446                }, vaPresentation);
    447 
    448                if (value == null || value == string.Empty)
    449                    ShowStatusBarMessage("No input value returning null.", NotificationLevel.Warning);
    450                
     558                    if (frequencyStats != null && frequencyStats != string.Empty&&!fStats.Contains(frequencyStats))
     559                    {
     560                        fStats.Add(frequencyStats);
     561                    }
     562                }
     563                if (v == probableKeylength)
     564                {
     565                    List<List<int>> keyList= new List<List<int>>();
     566                    List<int> chiList = new List<int>();
     567                    foreach (string c in fStats)
     568                    {
     569                        if (c != null)
     570                        {
     571                            CaesarAnalysis(c);
     572                            chiSquare(c);
     573                            keyList.Add(keys);
     574                            chiList.Add(shiftKey);
     575                        }
     576                    }
     577                    int[] probableKeyword = new int[probableKeylength];
     578                    for (int f = 0; f <= probableKeylength - 1; f++)
     579                    {
     580                        int [] tempKey = keyList.ElementAt(f).ToArray();
     581                        probableKeyword[f]=tempKey[0];
     582                        tempKey = null;
     583                    }
     584                    keyList = null;
     585                    StringBuilder keywordstring = new StringBuilder();
     586                    foreach(int r in probableKeyword)
     587                    {
     588                        keywordstring.Append(validchars[r]);
     589                    }
     590                    keywordOutput = keywordstring.ToString();
     591                    OnPropertyChanged("KeywordOutput");
     592                }
    451593            }
    452594        }
     
    466608
    467609        public void PostExecution()
    468         {
     610        {   
     611            frequencyStats = null;
    469612            Dispose();
    470613            kasiskiInput = null;
    471             probableKeylength = 0;
    472             //inputChange = false;
    473614            v = 0;
    474615        }
  • trunk/CrypPlugins/VigenereAnalyser/VigenereAnalyserSettings.cs

    r351 r388  
    1313    {
    1414        #region ISettings Members
    15 
     15        private int elf = 0;
    1616        private bool hasChanges = false;
     17        [ContextMenu("Letter Frequency", "Select the language to be analysed", 2, DisplayLevel.Beginner, ContextMenuControlType.ComboBox, null, new String[] { "English", "German", "French", "Spanish", "Italian", "Portugeese" })]
     18        [TaskPane("Letter Frequency", "Select the language to be analysed", null, 2, false, DisplayLevel.Experienced, ControlType.ComboBox, new String[] { "English", "German", "French", "Spanish", "Italian", "Portugeese" })]
     19        public int ELF // Expected Letter Frequencies
     20        {
     21            get { return this.elf; }
     22            set
     23            {
     24                if (((int)value) != elf) hasChanges = true;
     25                this.elf = (int)value;
     26                OnPropertyChanged("ELF");
     27            }
     28        }
    1729        public bool HasChanges
    1830        {
Note: See TracChangeset for help on using the changeset viewer.