source: trunk/CrypPlugins/CostFunction/CostFunction.cs @ 1476

Last change on this file since 1476 was 1476, checked in by malischewski, 12 years ago

fitness weight table implemented

File size: 30.8 KB
Line 
1/*                             
2   Copyright 2009 Team CrypTool (Sven Rech,Dennis Nolte,Raoul Falk,Nils Kopal), Uni Duisburg-Essen
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.Collections;
20using System.Linq;
21using System.Text;
22using Cryptool.PluginBase.Cryptography;
23using Cryptool.PluginBase;
24using Cryptool.PluginBase.Miscellaneous;
25using Cryptool.PluginBase.Analysis;
26using System.ComponentModel;
27using Cryptool.PluginBase.Control;
28using System.IO;
29using System.Text.RegularExpressions;
30using System.Threading;
31using System.Reflection;
32namespace Cryptool.Plugins.CostFunction
33{
34    [Author("Nils Kopal", "Nils.Kopal@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
35    [PluginInfo(false, "CostFunction", "CostFunction", null, "CostFunction/icon.png")]
36    public class CostFunction : IAnalysisMisc
37    {
38        #region private variables
39        private CostFunctionSettings settings = new CostFunctionSettings();
40        private byte[] inputText = null;
41        private byte[] outputText = null;
42        private double value = 0;
43        private Boolean stopped = true;
44        private IControlCost controlSlave;
45        private String bigramInput;
46        private double[,] bigramMatrix;
47        private IDictionary<string, double[]> corpusGrams;
48
49        private IDictionary<string, double[]> corpusBigrams; // Used for Weighted Bigrams/Trigrams Cost function
50        private IDictionary<string, double[]> corpusTrigrams;
51
52        //Fitness Weight Tables for Weighted Bigrams/Trigrams
53        private IDictionary<string, double> fwtMatthews = new Dictionary<string,double>();
54        private IDictionary<string, double> fwtAndrewJohnClark = new Dictionary<string,double>();
55        private IDictionary<string, double> fwtToemehArumugam = new Dictionary<string,double>();
56
57        private double betaMatthews = 1.0;
58        private double gammaMatthews = 1.0;
59
60        private double betaToemehArumugam = 1.0;
61        private double gammaToemehArumugam = 1.0;
62
63        private DataManager dataMgr = new DataManager(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); 
64        private const string DATATYPE = "transposition";
65
66        private IDictionary<String, DataFileMetaInfo> txtList;
67        private IDictionary<int, IDictionary<string, double[]>> statistics;
68
69        #endregion
70        #region internal constants
71        internal const int ABSOLUTE = 0;
72        internal const int PERCENTAGED = 1;
73        internal const int LOG2 = 2;
74        internal const int SINKOV = 3;
75        #endregion
76        #region CostFunctionInOut
77
78        [PropertyInfo(Direction.InputData, "Text Input", "Input your Text here", "", DisplayLevel.Beginner)]
79        public byte[] InputText
80        {
81            get
82            {
83                return inputText;
84            }
85            set
86            {
87                this.inputText = value;
88                OnPropertyChanged("InputText");
89            }
90        }
91
92        [PropertyInfo(Direction.OutputData, "Text Output", "Your Text will be send here", "", DisplayLevel.Beginner)]
93        public byte[] OutputText
94        {
95            get
96            {
97                return outputText;
98            }
99            set
100            {
101                this.outputText = value;
102                OnPropertyChanged("OutputText");
103            }
104        }
105
106        [PropertyInfo(Direction.OutputData, "Value", "The value of the function will be send here", "", DisplayLevel.Beginner)]
107        public double Value
108        {
109            get
110            {
111                return value;
112            }
113            set
114            {
115                this.value = value;
116                OnPropertyChanged("Value");
117            }
118        }
119
120        [PropertyInfo(Direction.ControlSlave, "SDES Slave", "Direct access to SDES.", "", DisplayLevel.Beginner)]
121        public IControlCost ControlSlave
122        {
123            get
124            {
125                if (controlSlave == null)
126                    controlSlave = new CostFunctionControl(this);
127                return controlSlave;
128            }
129        }
130
131        #endregion
132
133        #region IPlugin Members
134
135        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
136        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
137
138
139        public ISettings Settings
140        {
141            get { return this.settings; }
142            set { this.settings = (CostFunctionSettings)value; }
143        }
144
145        public System.Windows.Controls.UserControl Presentation
146        {
147            get { return null; }
148        }
149
150        public System.Windows.Controls.UserControl QuickWatchPresentation
151        {
152            get { return null; }
153        }
154
155        public void PreExecution()
156        {
157            this.stopped = false;
158        }
159
160        public void Execute()
161        {
162            if (this.InputText is Object && this.stopped == false)
163            {
164                int bytesToUse = 0;
165                try
166                {
167                    bytesToUse = int.Parse(settings.BytesToUse);
168                }
169                catch (Exception ex)
170                {
171                    GuiLogMessage("Entered bytesToUse is not an integer: " + ex.Message, NotificationLevel.Error);
172                    return;
173                }
174
175                if (bytesToUse > this.InputText.Length)
176                {
177                    bytesToUse = 0;
178                }
179
180                byte[] array;
181
182                if (bytesToUse > 0)
183                {
184                    //Create a new Array of size of bytesToUse if needed
185                    array = new byte[bytesToUse];
186                    for (int i = 0; i < bytesToUse && i < this.InputText.Length; i++)
187                    {
188                        array[i] = InputText[i];
189                    }
190                }
191                else
192                {
193                    array = this.InputText;
194                }
195
196                ProgressChanged(0.5, 1);
197                bigramInput = ByteArrayToString(array);
198                switch (settings.FunctionType)
199                {
200
201                    case 0: // Index of Coincedence
202                        this.Value = calculateIndexOfCoincidence(array);
203                        break;
204
205                    case 1: // Entropy
206                        this.Value = calculateEntropy(array);
207                        break;
208
209                    case 2: // Log 2 Bigrams
210                        this.Value = calculateNGrams(bigramInput, 2, 2,false);
211                        break;
212
213                    case 3: // sinkov Bigrams
214                        this.Value = calculateNGrams(bigramInput, 2, 3,false);
215                        break;
216                    case 4: //percentaged Bigrams
217                        this.Value = calculateNGrams(bigramInput, 2, 1,false);
218                        break;
219                    case 5: //regular expressions
220                        this.Value = regex(bigramInput);
221                        break;
222                    case 6: // Weighted Bigrams/Trigrams (used by genetic algorithm in transposition analyser
223                        this.Value = calculateWeighted(bigramInput);
224                        break;
225
226                    default:
227                        this.Value = -1;
228                        break;
229                }//end switch               
230
231                this.OutputText = this.InputText;
232                ProgressChanged(1, 1);
233
234            }//end if
235
236        }
237
238
239
240        public void PostExecution()
241        {
242            this.stopped = true;
243        }
244
245        public void Pause()
246        {
247
248        }
249
250        public void Stop()
251        {
252            this.stopped = false;
253        }
254
255        public void Initialize()
256        {
257
258        }
259
260        public void Dispose()
261        {
262
263        }
264
265        #endregion
266
267        #region INotifyPropertyChanged Members
268
269        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
270
271        public void OnPropertyChanged(string name)
272        {
273            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
274        }
275
276        private void ProgressChanged(double value, double max)
277        {
278            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
279        }
280
281        public void GuiLogMessage(string p, NotificationLevel notificationLevel)
282        {
283            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
284        }
285
286        #endregion
287
288        #region IPlugin Members
289
290        public event StatusChangedEventHandler OnPluginStatusChanged;
291
292        #endregion
293
294        #region private methods
295
296        private void fillfwts() {
297            fwtMatthews.Add("TH", 2.0);
298            fwtMatthews.Add("HE", 1.0);
299            fwtMatthews.Add("IN", 1.0);
300            fwtMatthews.Add("ER", 1.0);
301            fwtMatthews.Add("AN", 1.0);
302            fwtMatthews.Add("ED", 1.0);
303            fwtMatthews.Add("THE", 5.0);
304            fwtMatthews.Add("ING", 5.0);
305            fwtMatthews.Add("AND", 5.0);
306            fwtMatthews.Add("EEE", -5.0);
307
308            fwtToemehArumugam.Add("EEE", -5.0);
309            fwtToemehArumugam.Add("E ", 2.0);
310            fwtToemehArumugam.Add(" T", 1.0);
311            fwtToemehArumugam.Add("HE", 1.0);
312            fwtToemehArumugam.Add("TH", 1.0);
313            fwtToemehArumugam.Add(" A", 1.0);
314            fwtToemehArumugam.Add("   ", -10.0);
315            fwtToemehArumugam.Add("ING", 5.0);
316            fwtToemehArumugam.Add("S ", 1.0);
317            fwtToemehArumugam.Add("  ", -6.0);
318            fwtToemehArumugam.Add(" TH", 5.0);
319            fwtToemehArumugam.Add("THE", 5.0);
320            fwtToemehArumugam.Add("HE ", 5.0);
321            fwtToemehArumugam.Add("AND", 5.0);
322
323            fwtToemehArumugam.Add("ARE", 5.0);
324            fwtToemehArumugam.Add("NOT", 5.0);
325        }
326
327        private void weights(string ngram, int ngramlength)
328        {
329            if (fwtMatthews.TryGetValue(ngram, out value) && ngramlength == 2)
330            {
331                betaMatthews += value;
332            }
333
334            if (fwtMatthews.TryGetValue(ngram, out value) && ngramlength == 3)
335            {
336                gammaMatthews += value;
337            }
338
339
340            if (fwtToemehArumugam.TryGetValue(ngram, out value) && ngramlength == 2)
341            {
342                betaToemehArumugam += value;
343            }
344
345            if (fwtToemehArumugam.TryGetValue(ngram, out value) && ngramlength == 3)
346            {
347                gammaToemehArumugam += value;
348            }
349        }
350
351        //public double contains(string input)
352        //{
353        //    if (settings.Contains == null)
354        //    {
355        //        GuiLogMessage("There is no text to be searched for. Please insert text in the 'Contains text / Regular Expression' - Textarea", NotificationLevel.Error);
356        //        return new Double();
357        //    }
358
359        //    if (input.Contains(settings.Contains))
360        //    {
361        //        return 1.0;
362        //    }
363        //    return -1.0;
364        //}
365        public double calculateWeighted(string input)
366        {
367
368         
369
370            this.statistics = new Dictionary<int, IDictionary<string, double[]>>();
371
372            if (fwtMatthews == null && fwtToemehArumugam == null) { fillfwts(); }
373            if (corpusBigrams == null)
374            {
375                if (corpusTrigrams == null)
376                {
377
378                    corpusBigrams = GetStatistics(2); // Get Known Language statistics for Bigrams
379                    corpusTrigrams = GetStatistics(3); // and Trigrams
380                }
381
382            }
383            input = input.ToUpper();
384
385            double bigramscore = calculateNGrams(input, 2, 0, true);
386           // double trigramscore = calculateNGrams(input, 3, 0, true);
387
388            return -1.0*betaToemehArumugam * bigramscore;
389
390            /*
391            Dictionary<string, double> inputBiGrams = new Dictionary<string,double>();
392            Dictionary<string, double> inputTriGrams = new Dictionary<string,double>();
393           
394            // Count input Bigrams
395            foreach (string g in GramTokenizer.tokenize(input, 2, false))
396            {
397                if (inputBiGrams.ContainsKey(g))
398                {
399                    inputBiGrams[g] = inputBiGrams[g] + 1;
400                    if (fwtMatthews.TryGetValue(g, out value))
401                    {
402                        beta += value;
403                    }
404                }
405                else
406                {
407                    inputBiGrams.Add(g, 0);
408                    if (fwtMatthews.TryGetValue(g, out value))
409                    {
410                        beta += value;
411                    }
412                }
413            }
414           
415             debug
416            foreach (KeyValuePair<string, double[]> g in corpusBigrams)
417            {
418                GuiLogMessage(corpusBigrams[g.Key][0].ToString() + " " + g.Key + " " + corpusBigrams[g.Key][1].ToString(), NotificationLevel.Debug);
419            }
420           
421            // Count input TriGrams
422            foreach (string g in GramTokenizer.tokenize(input, 3, false))
423            {
424                if (inputTriGrams.ContainsKey(g))
425                {
426                    inputTriGrams[g] = inputTriGrams[g] + 1;
427                }
428                else
429                {
430                    inputTriGrams.Add(g, 0);
431                }
432            }
433           
434            //Union Bigrams
435            HashSet<string> allBigrams = new HashSet<string>(inputBiGrams.Keys);
436            allBigrams.UnionWith(corpusBigrams.Keys);
437
438            //Union Trigrams
439            HashSet<string> allTrigrams = new HashSet<string>(inputTriGrams.Keys);
440            allTrigrams.UnionWith(corpusTrigrams.Keys);
441
442            // Sum of all input Bigrams absolutes
443            double sumBigrams = 0.0;
444
445            // Sum of all input Trigrams absolutes
446            double sumTrigrams = 0.0;
447
448            // First part of the equation: Sum up all [K_b (i,j) - D_b (i,j)]
449            double bigramscore = 0.0;
450            foreach (string g in allBigrams)
451            {
452                if (corpusBigrams.ContainsKey(g) && inputBiGrams.ContainsKey(g))
453                {
454                    sumBigrams++;
455                    bigramscore += corpusBigrams[g][1] - inputBiGrams[g] / sumBigrams;
456                   
457                }
458                else if (!corpusBigrams.ContainsKey(g))
459                {
460                    sumBigrams++;
461                    bigramscore += 0.0 - inputBiGrams[g] / sumBigrams;
462                   
463                }
464                else if (!inputBiGrams.ContainsKey(g))
465                {
466                    sumBigrams++;
467                    bigramscore += corpusBigrams[g][1];
468                   
469                }
470            }
471
472            // Second part of the equation: Sum up all [K_t (i,j) - D_t (i,j)]
473            double Trigramscore = 0.0;
474            foreach (string g in allTrigrams)
475            {
476                if (corpusTrigrams.ContainsKey(g) && inputTriGrams.ContainsKey(g))
477                {
478                    sumTrigrams++;
479                    Trigramscore += corpusTrigrams[g][1] - inputTriGrams[g] / sumTrigrams;
480                }
481                else if (!corpusTrigrams.ContainsKey(g))
482                {
483                    sumTrigrams++;
484                    Trigramscore += 0.0 - inputTriGrams[g] / sumTrigrams;
485                }
486                else if (!inputTriGrams.ContainsKey(g))
487                {
488                    sumTrigrams++;
489                    Trigramscore += corpusTrigrams[g][1];
490                }
491            }
492            double total = beta * bigramscore + gamma * Trigramscore;
493            if (total != 0.0)
494            {
495                GuiLogMessage(total.ToString(), NotificationLevel.Debug);
496            }
497            return total;
498            */
499        }//end Execute
500
501        public double regex(string input)
502        {
503            if (settings.RegEx == null)
504            {
505                GuiLogMessage("There is no Regular Expression to be searched for. Please insert regex in the 'Regular Expression' - Textarea", NotificationLevel.Error);
506                return new Double();
507            }
508            try
509            {
510                Match match = Regex.Match(input, settings.RegEx);
511                if (match.Success)
512                {
513                    return 1.0;
514                }
515                else
516                {
517                    return -1.0;
518                }
519            }
520            catch (Exception e)
521            {
522                GuiLogMessage(e.Message, NotificationLevel.Error);
523                return -1.0;
524            }
525
526        }
527
528
529        /// <summary>
530        /// Calculates the Index of Coincidence multiplied with 100 of
531        /// a given byte array
532        ///
533        /// for example a German text has about 7.62
534        ///           an English text has about 6.61
535        /// </summary>
536        /// <param name="text">text to use</param>
537        /// <returns>Index of Coincidence</returns>
538        public double calculateIndexOfCoincidence(byte[] text)
539        {
540            return calculateIndexOfCoincidence(text, text.Length);
541        }
542
543        /// <summary>
544        /// Calculates the Index of Coincidence multiplied with 100 of
545        /// a given byte array
546        ///
547        /// for example a German text has about 7.62
548        ///           an English text has about 6.61
549        /// </summary>
550        /// <param name="text">text to use</param>
551        /// <param name="text">bytesToUse</param>
552        /// <returns>Index of Coincidence</returns>
553        public double calculateIndexOfCoincidence(byte[] text, int bytesToUse)
554        {
555            if (bytesToUse > text.Length)
556                bytesToUse = text.Length;
557
558            double[] n = new double[256];
559            //count all ASCII symbols
560            int counter = 0;
561            foreach (byte b in text)
562            {
563                n[b]++;
564                counter++;
565                if (counter == bytesToUse)
566                    break;
567            }
568
569            double coindex = 0;
570            //sum them
571            for (int i = 0; i < n.Length; i++)
572            {
573                coindex = coindex + n[i] * (n[i] - 1);
574            }
575
576            coindex = coindex / (bytesToUse);
577            coindex = coindex / (bytesToUse - 1);
578
579            return coindex * 100;
580
581        }//end calculateIndexOfCoincidence
582
583
584        private int lastUsedSize = -1;
585        private double[] xlogx;
586        private Mutex prepareMutex = new Mutex();
587
588        private void prepareEntropy(int size)
589        {
590            xlogx = new double[size + 1];
591            //precomputations for fast entropy calculation     
592            xlogx[0] = 0.0;
593            for (int i = 1; i <= size; i++)
594                xlogx[i] = -1.0 * i * Math.Log(i / (double)size) / Math.Log(2.0);
595        }
596
597        /// <summary>
598        /// Calculates the Entropy of a given byte array
599        /// for example a German text has about 4.0629
600        /// </summary>
601        /// <param name="text">text to use</param>
602        /// <returns>Entropy</returns>
603        public double calculateEntropy(byte[] text)
604        {
605            return calculateEntropy(text, text.Length);
606        }
607
608        /// <summary>
609        /// Calculates the Entropy of a given byte array
610        /// for example a German text has about 4.0629
611        /// </summary>
612        /// <param name="text">text to use</param>
613        /// <returns>Entropy</returns>
614        public double calculateEntropy(byte[] text, int bytesToUse)
615        {
616            return NativeCryptography.Crypto.calculateEntropy(text, bytesToUse);
617            if (bytesToUse > text.Length)
618           
619                bytesToUse = text.Length;
620           
621            if (lastUsedSize != bytesToUse)
622            {
623                try
624                {
625                    prepareMutex.WaitOne();
626                    if (lastUsedSize != bytesToUse)
627                    {
628                        prepareEntropy(bytesToUse);
629                        lastUsedSize = bytesToUse;
630                    }
631                }
632                finally
633                {
634                    prepareMutex.ReleaseMutex();
635                }
636            }
637
638            int[] n = new int[256];
639            //count all ASCII symbols
640            for (int counter = 0; counter < bytesToUse; counter++)
641            {
642                n[text[counter]]++;
643            }
644
645            double entropy = 0;
646            //calculate probabilities and sum entropy
647            for (int i = 0; i < 256; i++)
648                entropy += xlogx[n[i]];
649
650            return entropy / (double)bytesToUse;
651
652        }//end calculateEntropy
653
654        /// <summary>
655        /// This method calculates a trigram log2 score of a given text on the basis of a given grams dictionary.
656        /// Case is insensitive.
657        /// </summary>
658        /// <param name="input">The text to be scored</param>
659        /// <param name="length">n-gram length</param>
660        /// <returns>The trigram score result</returns>
661        public double calculateNGrams(string input, int length, int valueSelection, bool weighted)
662        {
663            this.statistics = new Dictionary<int, IDictionary<string, double[]>>();
664            double score = 0;
665            if (corpusBigrams == null && length == 2)
666            { corpusBigrams = GetStatistics(length); }
667
668            if (corpusTrigrams == null && length == 3)
669            { corpusTrigrams = GetStatistics(length); }
670            input = input.ToUpper();
671            // FIXME: case handling?
672
673            HashSet<string> inputGrams = new HashSet<string>();
674
675            foreach (string g in GramTokenizer.tokenize(input, length, false))
676            {
677                // ensure each n-gram is counted only once
678                if (inputGrams.Add(g))
679                {
680                    if (corpusBigrams.ContainsKey(g) && length == 2 )
681                    {
682                        score += corpusBigrams[g][valueSelection];
683                        if (weighted) { weights(g, 2); }
684                    }
685                    if (corpusTrigrams.ContainsKey(g) && length == 3)
686                    {
687                        score += corpusTrigrams[g][valueSelection];
688                        if (weighted) { weights(g, 3); }
689                    }
690                }
691            }
692
693            return score;
694        }
695        public IDictionary<string, double[]> GetStatistics(int gramLength)
696        {
697            // FIXME: inputTriGrams is not being used!
698
699            // FIXME: implement exception handling
700            if (!statistics.ContainsKey(gramLength))
701            {
702                //GuiLogMessage("Trying to load default statistics for " + gramLength + "-grams", NotificationLevel.Info);
703                statistics[gramLength] = LoadDefaultStatistics(gramLength);
704            }
705
706            return statistics[gramLength];
707        }
708
709        private IDictionary<string, double[]> LoadDefaultStatistics(int length)
710        {
711           
712            txtList = dataMgr.LoadDirectory(DATATYPE);
713           
714            switch (this.settings.StatisticsCorpus)
715            {
716                case 0:
717                    return calculateAbsolutes(txtList["statisticscorpusde"].DataFile.FullName, length);
718                   
719                case 1:
720                    return calculateAbsolutes(txtList["statisticscorpusen"].DataFile.FullName, length);
721                case 2:
722                    return calculateAbsolutes(this.settings.customFilePath, length);
723
724            }
725            return calculateAbsolutes(txtList["Statistics (DE)"].DataFile.FullName, length); //default
726           
727        }
728
729        private IDictionary<string, double[]> calculateAbsolutes(String path, int length)
730        {
731
732
733            Dictionary<string, double[]> grams = new Dictionary<string, double[]>();
734            int checkLength;
735            StreamReader reader = new StreamReader(path);
736            String text = reader.ReadToEnd();
737
738            text.ToUpper();
739            text = Regex.Replace(text, "[^A-Z]*", "");
740
741            if (length == 2)
742            {
743                checkLength = text.Length - 1;
744            }
745            else
746            {
747                checkLength = text.Length - 2;
748            }
749            for (int i = 0; i < checkLength; i++)
750            {
751                char a = text[i];
752                char b = text[i + 1];
753                String key;
754                if (length == 3) // Trigrams
755                {
756                    char c = text[i + 2];
757                    key = a.ToString();
758                    key = key + b.ToString();
759                    key = key + c.ToString();
760                }
761                else // Bigrams
762                {
763                    key = a.ToString();
764                    key = key + b.ToString();
765                }
766
767                if (!grams.ContainsKey(key))
768                {
769                    grams.Add(key, new double[] { 1, 0, 0, 0}); 
770                }
771                else
772                {
773                    grams[key][0] = grams[key][0] + 1.0;
774                }
775            }
776
777            double sum = grams.Values.Sum(item => item[ABSOLUTE]);
778            GuiLogMessage("Sum of all n-gram counts is: " + sum, NotificationLevel.Debug);
779
780            // calculate scaled values
781            foreach (double[] g in grams.Values)
782            {
783                g[PERCENTAGED] = g[ABSOLUTE] / sum;
784                g[LOG2] = Math.Log(g[ABSOLUTE], 2);
785                g[SINKOV] = Math.Log(g[PERCENTAGED], Math.E);
786            }
787
788
789
790            return grams;
791        }
792
793        public string ByteArrayToString(byte[] arr)
794        {
795            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
796            return enc.GetString(arr);
797        }
798
799
800        #endregion
801
802
803    }
804
805    #region slave
806
807    public class CostFunctionControl : IControlCost
808    {
809        public event IControlStatusChangedEventHandler OnStatusChanged;
810        #region IControlCost Members
811
812        private CostFunction plugin;
813
814        #endregion
815
816        /// <summary>
817        /// Constructor
818        /// </summary>
819        /// <param name="plugin"></param>
820        public CostFunctionControl(CostFunction plugin)
821        {
822            this.plugin = plugin;
823        }
824
825        public int getBytesToUse()
826        {
827            try
828            {
829                return int.Parse(((CostFunctionSettings)this.plugin.Settings).BytesToUse);
830            }
831            catch (Exception ex)
832            {
833                throw new Exception("Entered bytesToUse is not an integer: " + ex.Message);
834            }
835        }
836
837        /// <summary>
838        /// Returns the relation operator of the cost function which is set by by CostFunctionSettings
839        /// </summary>
840        /// <returns>RelationOperator</returns>
841        public RelationOperator getRelationOperator()
842        {
843            switch (((CostFunctionSettings)this.plugin.Settings).FunctionType)
844            {
845                case 0: //Index of coincidence
846                    return RelationOperator.LargerThen;
847                case 1: //Entropy
848                    return RelationOperator.LessThen;
849                case 2: // Bigrams: log 2
850                    return RelationOperator.LessThen;
851                case 3: // Sinkov
852                    return RelationOperator.LargerThen;
853                case 4: // percentage
854                    return RelationOperator.LargerThen;
855                case 5: // Regular Expression
856                    return RelationOperator.LargerThen;
857                case 6: // Weighted Bigrams/Trigrams
858                    return RelationOperator.LargerThen;
859
860                default:
861                    throw new NotImplementedException("The value " + ((CostFunctionSettings)this.plugin.Settings).FunctionType + " is not implemented.");
862            }//end switch
863        }//end getRelationOperator
864
865        /// <summary>
866        /// Calculates the cost function of the given text
867        ///
868        /// Cost function can be set by CostFunctionSettings
869        /// This algorithm uses a bytesToUse which can be set by CostFunctionSettings
870        /// If bytesToUse is set to 0 it uses the whole text
871        ///
872        /// </summary>
873        /// <param name="text"></param>
874        /// <returns>cost</returns>
875        public double calculateCost(byte[] text)
876        {
877            int bytesToUse = 0;
878            try
879            {
880                bytesToUse = ((CostFunctionSettings)this.plugin.Settings).BytesToUseInteger;
881            }
882            catch (Exception ex)
883            {
884                throw new Exception("Entered bytesToUse is not an integer: " + ex.Message);
885            }
886
887            switch (((CostFunctionSettings)this.plugin.Settings).FunctionType)
888            {
889                case 0: //Index of coincidence
890                    return plugin.calculateIndexOfCoincidence(text, bytesToUse);
891                case 1: //Entropy
892                    return plugin.calculateEntropy(text, bytesToUse);
893                case 2: // Bigrams: log 2
894                    return plugin.calculateNGrams(plugin.ByteArrayToString(text), 2, 2, false);
895                case 3: // Bigrams: Sinkov
896                    return plugin.calculateNGrams(plugin.ByteArrayToString(text), 2, 3, false);
897                case 4: // Bigrams: Percentaged
898                    return plugin.calculateNGrams(plugin.ByteArrayToString(text), 2, 1, false);
899                case 5: // regular expression
900                    return plugin.regex(plugin.ByteArrayToString(text));
901                case 6:
902                    return plugin.calculateWeighted(plugin.ByteArrayToString(text));
903                default:
904                    throw new NotImplementedException("The value " + ((CostFunctionSettings)this.plugin.Settings).FunctionType + " is not implemented.");
905            }//end switch
906        }
907
908
909    #endregion
910    }
911
912}
913
Note: See TracBrowser for help on using the repository browser.