source: trunk/CrypPlugins/TranspositionAnalyser/TranspositionAnalyser.cs @ 1990

Last change on this file since 1990 was 1990, checked in by weyers, 11 years ago

TranspositionAnalyser.cs cribanalysis stop variable bugfix

File size: 59.0 KB
Line 
1using System;
2using System.Linq;
3using System.Text;
4using Cryptool.PluginBase.Analysis;
5using Cryptool.PluginBase;
6using System.Windows.Controls;
7using System.ComponentModel;
8using Cryptool.PluginBase.Control;
9using Cryptool.PluginBase.Miscellaneous;
10using System.Collections;
11using System.Windows.Threading;
12using System.Threading;
13using System.Collections.Generic;
14
15
16
17namespace TranspositionAnalyser
18{
19
20    [Author("Daniel Kohnen, Julian Weyers, Simon Malischewski, Armin Wiefels", "kohnen@cryptool.org, weyers@cryptool.org, malischewski@cryptool.org, wiefels@cryptool.org", "Universität Duisburg-Essen", "http://www.uni-due.de")]
21    [PluginInfo(false, "Transposition Analyser", "Bruteforces the columnar transposition.", "TranspositionAnalyser/Description/TADescr.xaml", "TranspositionAnalyser/Images/icon.png")]
22    public class TranspositionAnalyser : IAnalysisMisc
23    {
24        private enum ReadInMode { byRow = 0, byColumn = 1 };
25        private enum PermutationMode { byRow = 0, byColumn = 1 };
26        private enum ReadOutMode { byRow = 0, byColumn = 1 };
27        private byte[] crib;
28        private byte[] input;
29        private Queue valuequeue;
30        LinkedList<ValueKey> list1;
31        private TranspositionAnalyserQuickWatchPresentation myPresentation;
32        private Random rd;
33        private AutoResetEvent ars;
34
35        TranspositionAnalyserSettings settings;
36        #region Properties
37        [PropertyInfo(Direction.InputData, "Input", "Input data for Analysis", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
38        public Byte[] Input
39        {
40            get
41            {
42                return this.input;
43            }
44
45            set
46            {
47                this.input = value;
48                OnPropertyChange("Input");
49
50            }
51        }
52
53        [PropertyInfo(Direction.InputData, "Crib", "Crib input", "Crib for Analysis", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
54        public Byte[] Crib
55        {
56            get
57            {
58                return this.crib;
59            }
60
61            set
62            {
63                this.crib = value;
64                OnPropertyChange("Crib");
65            }
66        }
67
68
69
70        #endregion
71
72        /// <summary>
73        /// Constructor
74        /// </summary>
75        public TranspositionAnalyser()
76        {
77            settings = new TranspositionAnalyserSettings();
78            myPresentation = new TranspositionAnalyserQuickWatchPresentation();
79            QuickWatchPresentation = myPresentation;
80            myPresentation.doppelClick += new EventHandler(this.doppelClick);
81            ars = new AutoResetEvent(false);
82        }
83
84        private void doppelClick(object sender, EventArgs e)
85        {
86            ListViewItem lvi = sender as ListViewItem;
87            ResultEntry rse = lvi.Content as ResultEntry;
88            Output = System.Text.Encoding.GetEncoding(1252).GetBytes(rse.Text);
89        }
90
91        private IControlEncryption controlMaster;
92        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.None, null)]
93        public IControlEncryption ControlMaster
94        {
95
96            get { return controlMaster; }
97            set
98            {
99                // value.OnStatusChanged += onStatusChanged;
100                controlMaster = value;
101                OnPropertyChanged("ControlMaster");
102            }
103        }
104
105
106
107        private IControlCost costMaster;
108        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.None, null)]
109        public IControlCost CostMaster
110        {
111            get { return costMaster; }
112            set
113            {
114                costMaster = value;
115            }
116        }
117
118        private byte[] output;
119        [PropertyInfo(Direction.OutputData, "Output", "output", "", DisplayLevel.Beginner)]
120        public byte[] Output
121        {
122            get
123            {
124                return this.output;
125            }
126            set
127            {
128                this.output = value;
129                OnPropertyChanged("Output");
130            }
131        }
132
133        public void GuiLogMessage(string message, NotificationLevel loglevel)
134        {
135            if (OnGuiLogNotificationOccured != null)
136                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
137        }
138
139        #region IPlugin Member
140
141        public event Cryptool.PluginBase.StatusChangedEventHandler OnPluginStatusChanged;
142
143        public event Cryptool.PluginBase.GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
144
145        public event Cryptool.PluginBase.PluginProgressChangedEventHandler OnPluginProgressChanged;
146
147        public ISettings Settings
148        {
149            get { return settings; }
150        }
151
152        public UserControl Presentation
153        {
154            get { return null; }
155        }
156
157        public UserControl QuickWatchPresentation
158        {
159            get;
160            private set;
161        }
162
163        public void PreExecution()
164        {
165
166        }
167
168        public void Execute()
169        {
170
171
172            if (this.input != null)
173            {
174                if (this.ControlMaster != null && this.input != null)
175                    this.process(this.ControlMaster);
176                else
177                {
178                    GuiLogMessage("You have to connect the Transposition Plugin to the Transpostion Analyzer Control!", NotificationLevel.Warning);
179                }
180            }
181            ProgressChanged(1, 1);
182        }
183
184        public void PostExecution()
185        {
186
187        }
188
189        public void Pause()
190        {
191
192        }
193
194        private Boolean stop;
195        public void Stop()
196        {
197            ars.Set();
198            stop = true;
199        }
200
201        public void Initialize()
202        {
203            this.settings.Analysis_method = 0;
204        }
205
206        public void Dispose()
207        {
208
209        }
210
211        private void onStatusChanged(IControl sender, bool readyForExecution)
212        {
213
214        }
215
216        public void OnPropertyChanged(string name)
217        {
218            if (PropertyChanged != null)
219            {
220                PropertyChanged(this, new PropertyChangedEventArgs(name));
221            }
222        }
223
224        private void OnPropertyChange(String propertyname)
225        {
226            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(propertyname));
227        }
228
229        public void process(IControlEncryption sender)
230        {
231            if (input != null)
232            {
233                switch (this.settings.Analysis_method)
234                {
235                    case 0: Output = costfunction_bruteforce(sender); GuiLogMessage("Starting Brute-Force Analysis", NotificationLevel.Info); break;
236
237                    case 1: GuiLogMessage("Starting Analysis with crib", NotificationLevel.Info); cribAnalysis(sender, this.crib, this.input); break;
238
239                    case 2: GuiLogMessage("Starting genetic analysis", NotificationLevel.Info); geneticAnalysis(sender); break;
240                }
241            }
242            else
243            {
244                GuiLogMessage("No Input!", NotificationLevel.Error);
245            }
246
247
248        }
249
250        private void updateToplist(LinkedList<ValueKey> costList)
251        {
252            LinkedListNode<ValueKey> node;
253
254            while (valuequeue.Count != 0)
255            {
256                ValueKey vk = (ValueKey)valuequeue.Dequeue();
257                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
258                {
259                    if (vk.value > costList.Last().value)
260                    {
261                        node = costList.First;
262                        int i = 0;
263                        while (node != null)
264                        {
265                            if (vk.value > node.Value.value)
266                            {
267                                costList.AddBefore(node, vk);
268                                costList.RemoveLast();
269                                if (i == 0)
270                                {
271                                    Output = vk.decryption;
272                                }
273                                // value_threshold = costList.Last.Value.value;
274                                break;
275                            }
276                            node = node.Next;
277                            i++;
278                        }//end while
279                    }//end if
280                }
281                else
282                {
283                    if (vk.value < costList.Last().value)
284                    {
285                        node = costList.First;
286                        int i = 0;
287                        while (node != null)
288                        {
289                            if (vk.value < node.Value.value)
290                            {
291                                costList.AddBefore(node, vk);
292                                costList.RemoveLast();
293                                if (i == 0)
294                                {
295                                    Output = vk.decryption;
296                                }
297
298                                // value_threshold = costList.Last.Value.value;
299                                break;
300                            }
301                            node = node.Next;
302                            i++;
303                        }//end while
304                    }//end if
305                }
306            }
307        }
308
309        public void ProgressChanged(double value, double max)
310        {
311            if (OnPluginProgressChanged != null)
312            {
313                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
314
315            }
316        }
317
318        private void showProgress(DateTime startTime, long size, long sum)
319        {
320            LinkedListNode<ValueKey> linkedListNode;
321            if (QuickWatchPresentation.IsVisible && !stop)
322            {
323                DateTime currentTime = DateTime.Now;
324
325                TimeSpan elapsedtime = DateTime.Now.Subtract(startTime); ;
326                TimeSpan elapsedspan = new TimeSpan(elapsedtime.Days, elapsedtime.Hours, elapsedtime.Minutes, elapsedtime.Seconds, 0);
327
328
329
330                TimeSpan span = currentTime.Subtract(startTime);
331                int seconds = span.Seconds;
332                int minutes = span.Minutes;
333                int hours = span.Hours;
334                int days = span.Days;
335
336                long allseconds = seconds + 60 * minutes + 60 * 60 * hours + 24 * 60 * 60 * days;
337                if (allseconds == 0) allseconds = 1;
338
339                if (allseconds == 0)
340                    allseconds = 1;
341
342                long keysPerSec = sum / allseconds;
343
344                long keystodo = (size - sum);
345
346               
347                if (keysPerSec == 0)
348                    keysPerSec = 1;
349
350                long secstodo = keystodo / keysPerSec;
351
352                //dummy Time
353                DateTime endTime = new DateTime(1970, 1, 1);
354                try
355                {
356                    endTime = DateTime.Now.AddSeconds(secstodo);
357                }
358                catch
359                {
360
361                }
362
363
364                ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
365                {
366
367                    ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).startTime.Content = "" + startTime;
368                    ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Content = "" + keysPerSec;
369
370
371                    if (endTime != (new DateTime(1970, 1, 1)))
372                    {
373                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).timeLeft.Content = "" + endTime.Subtract(DateTime.Now);
374                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).elapsedTime.Content = "" + elapsedspan;
375                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).endTime.Content = "" + endTime;
376                    }
377                    else
378                    {
379                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).timeLeft.Content = "incalculable";
380
381                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).endTime.Content = "in a galaxy far, far away...";
382                    }
383                    if (list1 != null)
384                    {
385                        linkedListNode = list1.First;
386                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).entries.Clear();
387                        int i = 0;
388                        while (linkedListNode != null)
389                        {
390                            i++;
391                            ResultEntry entry = new ResultEntry();
392                            entry.Ranking = i.ToString();
393
394
395                            String dec = System.Text.Encoding.ASCII.GetString(linkedListNode.Value.decryption);
396                            if (dec.Length > 2500) // Short strings need not to be cut off
397                            {
398                                dec = dec.Substring(0, 2500);
399                            }
400                            entry.Text = dec;
401                            entry.Key = linkedListNode.Value.key;
402                            entry.Value = Math.Round(linkedListNode.Value.value, 2) + "";
403
404
405                            ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).entries.Add(entry);
406
407                            linkedListNode = linkedListNode.Next;
408                        }
409
410                    }
411                }
412                , null);
413
414            }
415        }
416
417        #endregion
418
419        #region INotifyPropertyChanged Member
420
421        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
422
423        #endregion
424
425        #region bruteforce
426
427        private int[] getBruteforceSettings()
428        {
429            int[] set;
430            int sum = 0;
431            if (settings.ColumnColumnColumn) sum++;
432            if (settings.ColumnColumnRow) sum++;
433            if (settings.RowColumnColumn) sum++;
434            if (settings.RowColumnRow) sum++;
435
436            if (sum > 0)
437            {
438                set = new int[sum];
439                int count = 0;
440                if (settings.ColumnColumnColumn)
441                {
442                    set[count] = 0;
443                    count++;
444                }
445                if (settings.ColumnColumnRow)
446                {
447                    set[count] = 1;
448                    count++;
449                }
450                if (settings.RowColumnColumn)
451                {
452                    set[count] = 2;
453                    count++;
454                }
455
456                if (settings.RowColumnRow)
457                {
458                    set[count] = 3;
459                    count++;
460                }
461                return set;
462            }
463            else
464            {
465                return null;
466            }
467
468        }
469
470        private byte[] costfunction_bruteforce(IControlEncryption sender)
471        {
472            valuequeue = Queue.Synchronized(new Queue());
473            int[] set = getBruteforceSettings();
474            stop = false;
475            if (sender != null && costMaster != null && set != null)
476            {
477                GuiLogMessage("start", NotificationLevel.Info);
478                double best = Double.MinValue;
479
480                if (costMaster.getRelationOperator() == RelationOperator.LessThen)
481                {
482                    best = Double.MaxValue;
483                }
484
485                list1 = getDummyLinkedList(best);
486                String best_text = "";
487                ArrayList list = null;
488
489
490                //Just for fractional-calculation:
491                PermutationGenerator per = new PermutationGenerator(2);
492                DateTime starttime = DateTime.Now;
493                DateTime lastUpdate = DateTime.Now;
494
495                int max = 0;
496                max = settings.MaxLength;
497                //GuiLogMessage("Max: " + max, NotificationLevel.Info);
498                if (max > 1 && max < 21)
499                {
500                    long size = 0;
501                    for (int i = 2; i <= max; i++)
502                    {
503                        size = size + per.getFactorial(i);
504                    }
505                    size = size * set.Length;
506                    long sum = 0;
507                    for (int i = 1; i <= max; i++)
508                    {
509                        // for every selected bruteforce mode:
510                        for (int s = 0; s < set.Length; s++)
511                        {
512                            switch (set[s])
513                            {
514                                case (0):
515                                    controlMaster.changeSettings("ReadIn", ReadInMode.byColumn);
516                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
517                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byColumn);
518                                    break;
519                                case (1):
520                                    controlMaster.changeSettings("ReadIn", ReadInMode.byColumn);
521                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
522                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byRow);
523                                    break;
524                                case (2):
525                                    controlMaster.changeSettings("ReadIn", ReadInMode.byRow);
526                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
527                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byColumn);
528                                    break;
529                                case (3):
530                                    controlMaster.changeSettings("ReadIn", ReadInMode.byRow);
531                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
532                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byRow);
533                                    break;
534                            }
535
536                            per = new PermutationGenerator(i);
537
538                            while (per.hasMore() && !stop)
539                            {
540                                best = list1.Last.Value.value;
541                                int[] key = per.getNext();
542                                byte[] b = new byte[key.Length];
543                                for (int j = 0; j < b.Length; j++)
544                                {
545                                    b[j] = Convert.ToByte(key[j]);
546                                }
547                                byte[] dec = sender.Decrypt(input, b, null);
548                                if (dec != null)
549                                {
550                                    double val = costMaster.calculateCost(dec);
551                                    if (val.Equals(new Double()))
552                                    {
553                                        return new byte[0];
554                                    }
555                                    if (costMaster.getRelationOperator() == RelationOperator.LessThen)
556                                    {
557                                        if (val <= best)
558                                        {
559                                            ValueKey valkey = new ValueKey();
560                                            String keyStr = "";
561                                            foreach (int xyz in key)
562                                            {
563                                                keyStr += xyz + ", ";
564                                            }
565                                            valkey.decryption = dec;
566                                            valkey.key = keyStr;
567                                            valkey.value = val;
568                                            valuequeue.Enqueue(valkey);
569                                        }
570                                    }
571                                    else
572                                    {
573                                        if (val >= best)
574                                        {
575                                            ValueKey valkey = new ValueKey();
576                                            String keyStr = "";
577                                            foreach (int xyz in key)
578                                            {
579                                                keyStr += xyz;
580                                            }
581                                            valkey.decryption = dec;
582                                            valkey.key = keyStr;
583                                            valkey.value = val;
584                                            valuequeue.Enqueue(valkey);
585                                        }
586                                    }
587                                }
588
589                                sum++;
590                                if (DateTime.Now >= lastUpdate.AddMilliseconds(1000))
591                                {
592                                    updateToplist(list1);
593                                    showProgress(starttime, size, sum);
594                                    ProgressChanged(sum, size);
595                                    lastUpdate = DateTime.Now;
596                                }
597                            }
598                        }
599                    }
600                    if (list != null)
601                    {
602                        int i = 1;
603                        foreach (string tmp in list)
604                        {
605                            GuiLogMessage("ENDE (" + i++ + ")" + best + ": " + tmp, NotificationLevel.Info);
606                        }
607                    }
608                    else
609                    {
610                        GuiLogMessage("ENDE " + best + ": " + best_text, NotificationLevel.Info);
611                    }
612                    return list1.First.Value.decryption;
613                }
614                else
615                {
616                    GuiLogMessage("Error: Check transposition bruteforce length. Max length is 20!", NotificationLevel.Error);
617                    return null;
618                }
619            }
620            else
621            {
622                GuiLogMessage("Error: No costfunction applied.", NotificationLevel.Error);
623                return null;
624            }
625        }
626
627        #endregion
628
629        private LinkedList<ValueKey> getDummyLinkedList(double best)
630        {
631            ValueKey valueKey = new ValueKey();
632            valueKey.value = best;
633            valueKey.key = "dummykey";
634            valueKey.decryption = new byte[0];
635            LinkedList<ValueKey> list = new LinkedList<ValueKey>();
636            LinkedListNode<ValueKey> node = list.AddFirst(valueKey);
637            for (int i = 0; i < 9; i++)
638            {
639                node = list.AddAfter(node, valueKey);
640            }
641            return list;
642        }
643
644        #region cribAnalysis
645
646        private ArrayList bestlist;
647        private ArrayList valList;
648        private long sumBinKeys;
649        private int countBinKeys;
650        private int binKeysPerSec;
651        private int[] keysLastTenSecs;
652        private int poskeysLastTenSecs;
653        private int searchPosition;
654        private DateTime starttime;
655        private DateTime lastUpdate;
656
657        private void cribAnalysis(IControlEncryption sender, byte[] crib, byte[] cipher)
658        {
659            stop = false;
660            valList = new ArrayList();
661            bestlist = new ArrayList();
662            valuequeue = Queue.Synchronized(new Queue());
663            starttime = DateTime.Now;
664            lastUpdate = DateTime.Now;
665
666            int maxKeylength = settings.CribSearchKeylength;
667
668            if (maxKeylength <= 1)
669            {
670                GuiLogMessage("Keylength must be greater than 1", NotificationLevel.Error);
671                return;
672            }
673
674            if (maxKeylength > crib.Length)
675            {
676                GuiLogMessage("Crib must be longer than maximum keylength", NotificationLevel.Error);
677                return;
678            }
679
680            if (crib == null)
681            {
682                GuiLogMessage("crib == null", NotificationLevel.Error);
683                return;
684            }
685
686            if (cipher== null)
687            {
688                GuiLogMessage("cipher == null", NotificationLevel.Error);
689                return;
690            }
691
692            if (crib.Length < 2)
693            {
694                GuiLogMessage("Crib is too short.", NotificationLevel.Error);
695                return;
696            }
697
698            for (int keylength = 2; keylength <= maxKeylength; keylength++)
699            {
700                sumBinKeys += binomial_iter(keylength, cipher.Length % keylength);
701            }
702
703            keysLastTenSecs = new int[10];
704            poskeysLastTenSecs = 0;
705
706            for (int keylength = 2; keylength <= maxKeylength; keylength++)
707            {
708                int[] binaryKey = getDefaultBinaryKey(cipher, keylength);
709                int[] firstKey = (int[])binaryKey.Clone();
710
711                do
712                {
713                    countBinKeys++;
714                    binKeysPerSec++;
715                    byte[,] cipherMatrix = cipherToMatrix(cipher, binaryKey);
716                    byte[,] cribMatrix = cribToMatrix(crib, keylength);
717                    ArrayList possibleList = analysis(sender, cipher, cipherMatrix, cribMatrix, keylength);
718
719                    Boolean eq;
720                    foreach (int[] k in possibleList)
721                    {
722                        eq = false;
723                        foreach (int[] kbest in bestlist)
724                        {
725                            if (arrayEquals(k, kbest))
726                                eq = true;
727                        }
728                        if (!eq)
729                        {
730                            addToBestList(sender, k);
731                        }
732                    }
733
734                    binaryKey = nextPossible(binaryKey, binaryKey.Sum());
735
736                    if (DateTime.Now >= lastUpdate.AddMilliseconds(1000))
737                    {
738                        keysLastTenSecs[(poskeysLastTenSecs++ % 10)] = binKeysPerSec;
739
740                        if (DateTime.Now < starttime.AddMilliseconds(12000))
741                        {
742                            showProgressCribAnalysis(starttime, sumBinKeys, countBinKeys, binKeysPerSec);
743                        }
744                        else
745                        {
746                            int keysPerSec = keysLastTenSecs.Sum() / 10;
747                            showProgressCribAnalysis(starttime, sumBinKeys, countBinKeys, keysPerSec);
748                        }
749
750                        showBestKeysCribSearch();
751                        binKeysPerSec = 0;
752                        lastUpdate = DateTime.Now;
753                        showProgress(starttime, sumBinKeys, countBinKeys);
754                        ProgressChanged(countBinKeys, sumBinKeys);
755
756                       
757                    }
758
759                } while (!arrayEquals(firstKey, binaryKey));
760            }
761
762            showBestKeysCribSearch();
763            showProgress(starttime, 1, 1);
764            ProgressChanged(1, 1);
765        }
766
767        private void showBestKeysCribSearch()
768        {
769            valList = updateValueKeyArrayList(valList, 12);
770
771            Double best = Double.MinValue;
772
773            if (costMaster.getRelationOperator() == RelationOperator.LessThen)
774            {
775                best = Double.MaxValue;
776            }
777
778            foreach (ValueKey v in valList)
779            {
780                valuequeue.Enqueue(v);
781            }
782
783            list1 = getDummyLinkedList(best);
784            updateToplist(list1);
785        }
786
787        private void addToBestList(IControlEncryption sender, int[] k)
788        {
789            int[] first = (int[])k.Clone();
790
791            do
792            {
793                bestlist.Add((int[])k.Clone());
794
795                int[] keyPlusOne = new int[k.Length];
796                for (int i = 0; i < k.Length; i++)
797                {
798                    keyPlusOne[i] = k[i] + 1;
799                }
800
801                byte[] key = intArrayToByteArray(keyPlusOne);
802
803                ValueKey tmpValue = new ValueKey();
804                byte[] dec = sender.Decrypt(input, key, null);
805                double val = costMaster.calculateCost(dec);
806
807                String keyStr = "";
808                foreach (byte bb in key)
809                {
810                    keyStr += bb + ", ";
811                }
812
813                tmpValue.keyArray = key;
814                tmpValue.decryption = dec;
815                tmpValue.key = keyStr;
816                tmpValue.value = val;
817                valList.Add(tmpValue);
818
819                k = shiftKey(k);
820
821            } while (!arrayEquals(k, first));
822        }
823
824        private int[] shiftKey(int[] key)
825        {
826            int[] ret = new int[key.Length];
827            ret[0] = key[key.Length - 1];
828            for (int i = 1; i < ret.Length; i++)
829            {
830                ret[i] = key[i - 1];
831            }
832
833            return ret;
834        }
835
836        private ArrayList analysis(IControlEncryption sender, byte[] cipher, byte[,] cipherMatrix, byte[,] cribMatrix, int keylength)
837        {
838            ArrayList possibleList = new ArrayList();
839            int[] key = new int[keylength];
840            for (int i = 0; i < key.Length; i++)
841            {
842                key[i] = -1;
843            }
844
845            int keyPosition = 0;
846            Boolean end = false;
847
848            while (!end)
849            {
850                Boolean check = true;
851                if (keyPosition == -1)
852                {
853                    end = true;
854                    break;
855                }
856
857                if (key[keyPosition] == -1)
858                {
859                    for (int i = 0; i < key.Length; i++)
860                    {
861                        Boolean inUse = false;
862                        for (int j = 0; j < keyPosition; j++)
863                        {
864                            if (i == key[j])
865                                inUse = true;
866                        }
867
868                        if (!inUse)
869                        {
870                            key[keyPosition] = i;
871                            break;
872                        }
873                    }
874                }
875                else
876                {
877                    Boolean incrementPosition = true;
878
879                    if (keyPosition == 0 && searchPosition != -1)
880                    {
881                        byte[] cipherCol = getColumn(cipherMatrix, key[keyPosition], key.Length);
882                        byte[] cribCol = getColumn(cribMatrix, keyPosition, key.Length);
883                        int tmpSearchPosition = searchPosition;
884                        searchPosition = -1;
885
886                        if (containsAndCheckCribPosition(cipherCol, cribCol, tmpSearchPosition + 1))
887                        {
888                            keyPosition++;
889                            check = false;
890                            incrementPosition = false;
891                        }
892                    }
893
894                    if (incrementPosition)
895                    {
896                        Boolean inUse = true;
897
898                        while (inUse)
899                        {
900                            key[keyPosition] = key[keyPosition] + 1;
901                            inUse = false;
902
903                            for (int j = 0; j < keyPosition; j++)
904                            {
905                                if (key[keyPosition] == key[j])
906                                    inUse = true;
907                            }
908                        }
909
910                        if (key[keyPosition] >= key.Length)
911                        {
912                            key[keyPosition] = -1;
913                            keyPosition--;
914                            check = false;
915                        }
916                    }
917                }
918
919                if (keyPosition == 0 && key[0] == -1)
920                {
921                    break;
922                }
923
924                if (check)
925                {
926                    if (keyPosition >= 0 && keyPosition <= key.Length)
927                    {
928                        byte[] cipherCol = getColumn(cipherMatrix, key[keyPosition], key.Length);
929                        byte[] cribCol = getColumn(cribMatrix, keyPosition, key.Length);
930
931                        if (containsAndCheckCribPosition(cipherCol, cribCol, 0))
932                            keyPosition++;
933
934                        if (keyPosition == key.Length)
935                        {
936                            possibleList.Add(key.Clone());
937
938                            keyPosition--;
939                            key[keyPosition] = -1;
940                            keyPosition--;
941                        }
942
943                        if (keyPosition == 0)
944                        {
945                            searchPosition = -1;
946                        }
947                    }
948                }
949            }
950            return possibleList;
951        }
952
953        private byte[] getColumn(byte[,] input, int column, int keylength)
954        {
955            byte[] output = new byte[input.Length / keylength];
956            for (int i = 0; i < output.Length; i++)
957            {
958                output[i] = input[column, i];
959            }
960            return output;
961        }
962
963        Boolean containsAndCheckCribPosition(byte[] one, byte[] two, int startSearchAt)
964        {
965            for (int i = startSearchAt; i < one.Length; i++)
966            {
967                if (one[i] == two[0])
968                {
969                    for (int j = 1; j < two.Length; j++)
970                    {
971                        if (i + j >= one.Length)
972                        {
973                            break;
974                        }
975                        if (searchPosition != -1)
976                        {
977                            // höchstens 2 Positionen nach links oder rechts
978                            if (Math.Sqrt((searchPosition - i) * (searchPosition - i)) > 2)
979                            {
980                                break;
981                            }
982                        }
983
984                        if (two[j].Equals(new byte()))
985                        {
986                            if (searchPosition == -1)
987                            {
988                                searchPosition = i;
989                            }
990                            return true;
991                        }
992                        else
993                        {
994                            if (one[i + j] != two[j])
995                            {
996                                break;
997                            }
998
999                            if (j == two.Length - 1)
1000
1001                                if (searchPosition == -1)
1002                                {
1003                                    searchPosition = i;
1004                                }
1005                            return true;
1006                        }
1007                    }
1008                }
1009            }
1010            return false;
1011        }
1012
1013        private Boolean arrayEquals(int[] a, int[] b)
1014        {
1015            if (a.Length != b.Length) return false;
1016            for (int i = 0; i < a.Length; i++)
1017            {
1018                if (a[i] != b[i])
1019                    return false;
1020            }
1021            return true;
1022        }
1023
1024        private int[] nextPossible(int[] input, int numberOfOnes)
1025        {
1026            Boolean found = false;
1027            while (!found)
1028            {
1029                input = addBinOne(input);
1030                if (count(input, 1) == numberOfOnes)
1031                    found = true;
1032            }
1033            return input;
1034        }
1035
1036        private int count(int[] array, int countThis)
1037        {
1038            int c = 0;
1039            foreach (int i in array)
1040            {
1041                if (i == countThis)
1042                    c++;
1043            }
1044            return c;
1045        }
1046
1047        private int[] addBinOne(int[] input)
1048        {
1049            int i = input.Length - 1;
1050            while (i >= 0 && input[i] == 1)
1051            {
1052                input[i] = 0;
1053                i--;
1054            }
1055            if (i >= 0)
1056                input[i] = 1;
1057            return input;
1058        }
1059
1060        private long binomial_iter(int n, int k)
1061        {
1062            long produkt = 1;
1063            if (k > n / 2)
1064                k = n - k;
1065            for (int i = 1; i <= k; ++i)
1066            {
1067                produkt = produkt * n-- / i;
1068            }
1069            return produkt;
1070        }
1071
1072        private int[] getDefaultBinaryKey(byte[] cipher, int keylength)
1073        {
1074            int offset = cipher.Length % keylength;
1075            int[] binaryKey = new int[keylength];
1076
1077            for (int i = 0; i < keylength; i++)
1078            {
1079                if (i + offset < keylength)
1080                {
1081                    binaryKey[i] = 0;
1082                }
1083                else
1084                {
1085                    binaryKey[i] = 1;
1086                }
1087            }
1088            if (binaryKey.Sum() == 0)
1089            {
1090                for (int i = 0; i < keylength; i++)
1091                {
1092                    binaryKey[i] = 1;
1093                }
1094            }
1095
1096            return binaryKey;
1097        }
1098
1099        private byte[,] cipherToMatrix(byte[] cipher, int[] key)
1100        {
1101            int height = cipher.Length / key.Length;
1102            if (cipher.Length % key.Length != 0)
1103            {
1104                height++;
1105            }
1106
1107            byte[,] cipherMatrix = new byte[key.Length, height];
1108            int pos = 0;
1109
1110            for (int a = 0; a < key.Length; a++)
1111            {
1112                for (int b = 0; b < height; b++)
1113                {
1114                    if ((b == height - 1) && (key[a] != 1))
1115                    {
1116                        break;
1117                    }
1118                    else
1119                    {
1120                        cipherMatrix[a, b] = cipher[pos++];
1121                    }
1122                }
1123            }
1124            return cipherMatrix;
1125        }
1126
1127        private byte[,] cribToMatrix(byte[] crib, int keylength)
1128        {
1129            int height = crib.Length / keylength;
1130            if (crib.Length % keylength != 0)
1131            {
1132                height++;
1133            }
1134
1135            byte[,] cribMatrix = new byte[keylength, height];
1136            int pos = 0;
1137
1138            for (int b = 0; b < height; b++)
1139            {
1140                for (int a = 0; a < keylength; a++)
1141                {
1142                    if (pos < crib.Length)
1143                        cribMatrix[a, b] = crib[pos++];
1144                }
1145            }
1146            return cribMatrix;
1147        }
1148
1149        private void showProgressCribAnalysis(DateTime startTime, long size, long sum, long keysPerSec)
1150        {
1151            LinkedListNode<ValueKey> linkedListNode;
1152            if (QuickWatchPresentation.IsVisible && !stop)
1153            {
1154                DateTime currentTime = DateTime.Now;
1155
1156                TimeSpan elapsedtime = DateTime.Now.Subtract(startTime); ;
1157                TimeSpan elapsedspan = new TimeSpan(elapsedtime.Days, elapsedtime.Hours, elapsedtime.Minutes, elapsedtime.Seconds, 0);
1158
1159
1160
1161                TimeSpan span = currentTime.Subtract(startTime);
1162                int seconds = span.Seconds;
1163                int minutes = span.Minutes;
1164                int hours = span.Hours;
1165                int days = span.Days;
1166
1167                long allseconds = seconds + 60 * minutes + 60 * 60 * hours + 24 * 60 * 60 * days;
1168                if (allseconds == 0) allseconds = 1;
1169
1170                long keystodo = (size - sum);
1171
1172                long secstodo = keystodo / keysPerSec;
1173
1174                //dummy Time
1175                DateTime endTime = new DateTime(1970, 1, 1);
1176                try
1177                {
1178                    endTime = DateTime.Now.AddSeconds(secstodo);
1179                }
1180                catch
1181                {
1182
1183                }
1184
1185
1186                ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1187                {
1188
1189                    ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).startTime.Content = "" + startTime;
1190                    ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Content = "" + keysPerSec;
1191
1192
1193                    if (endTime != (new DateTime(1970, 1, 1)))
1194                    {
1195                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).timeLeft.Content = "" + endTime.Subtract(DateTime.Now);
1196                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).elapsedTime.Content = "" + elapsedspan;
1197                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).endTime.Content = "" + endTime;
1198                    }
1199                    else
1200                    {
1201                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).timeLeft.Content = "incalculable";
1202
1203                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).endTime.Content = "in a galaxy far, far away...";
1204                    }
1205                    if (list1 != null)
1206                    {
1207                        linkedListNode = list1.First;
1208                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).entries.Clear();
1209                        int i = 0;
1210                        while (linkedListNode != null)
1211                        {
1212                            i++;
1213                            ResultEntry entry = new ResultEntry();
1214                            entry.Ranking = i.ToString();
1215
1216
1217                            String dec = System.Text.Encoding.ASCII.GetString(linkedListNode.Value.decryption);
1218                            if (dec.Length > 2500) // Short strings need not to be cut off
1219                            {
1220                                dec = dec.Substring(0, 2500);
1221                            }
1222                            entry.Text = dec;
1223                            entry.Key = linkedListNode.Value.key;
1224                            entry.Value = Math.Round(linkedListNode.Value.value, 2) + "";
1225
1226
1227                            ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).entries.Add(entry);
1228
1229                            linkedListNode = linkedListNode.Next;
1230                        }
1231
1232                    }
1233                }
1234
1235
1236                , null);
1237
1238            }
1239        }
1240
1241        private byte[] intArrayToByteArray(int[] input)
1242        {
1243            byte[] output = new byte[input.Length];
1244            for (int i = 0; i < output.Length; i++)
1245            {
1246                output[i] = Convert.ToByte(input[i]);
1247            }
1248
1249            return output;
1250        }
1251
1252        #endregion
1253
1254        #region genetic analysis
1255
1256        private void geneticAnalysis(IControlEncryption sender)
1257        {
1258            stop = false;
1259
1260            valuequeue = Queue.Synchronized(new Queue());
1261
1262            int size = settings.Iterations;
1263            int keylength = settings.KeySize;
1264            int repeatings = settings.Repeatings;
1265
1266            if (size < 2 || keylength < 2 || repeatings < 1)
1267            {
1268                GuiLogMessage("Check keylength and iterations", NotificationLevel.Error);
1269                return;
1270            }
1271
1272            if (sender == null || costMaster == null || input == null)
1273            {
1274                if (sender == null)
1275                {
1276                    GuiLogMessage("sender == null", NotificationLevel.Error);
1277                }
1278                if (costMaster == null)
1279                {
1280                    GuiLogMessage("costMaster == null", NotificationLevel.Error);
1281                }
1282                if (input == null)
1283                {
1284                    GuiLogMessage("input == null", NotificationLevel.Error);
1285                }
1286                return;
1287            }
1288            DateTime startTime = DateTime.Now;
1289            DateTime lastUpdate = DateTime.Now;
1290
1291            ArrayList bestOf = null;
1292
1293            for (int it = 0; it < repeatings; it++)
1294            {
1295                ArrayList valList = new ArrayList();
1296
1297                for (int i = 0; i < 12; i++)
1298                {
1299                    byte[] rndkey = randomArray(keylength);
1300                    byte[] dec = sender.Decrypt(input, rndkey, null);
1301                    double val = costMaster.calculateCost(dec);
1302
1303                    String keyStr = "";
1304                    foreach (byte tmp in rndkey)
1305                    {
1306                        keyStr += tmp + ", ";
1307                    }
1308
1309
1310                    ValueKey v = new ValueKey();
1311                    v.decryption = dec;
1312                    v.key = keyStr;
1313                    v.keyArray = rndkey;
1314                    v.value = val;
1315                    valList.Add(v);
1316                }
1317
1318                valuequeue = Queue.Synchronized(new Queue());
1319
1320                int iteration = 0;
1321                while (iteration < size && !stop)
1322                {
1323                    valList = updateValueKeyArrayList(valList, 12);
1324
1325
1326                    //valListe sortieren
1327                    ArrayList tmpList = new ArrayList(12);
1328
1329                    double best = Double.MinValue;
1330                    int bestpos = -1;
1331                    for (int a = 0; a < 12; a++)
1332                    {
1333                        best = Double.MinValue;
1334                        bestpos = -1;
1335
1336                        for (int b = 0; b < valList.Count; b++)
1337                        {
1338                            ValueKey v = (ValueKey)valList[b];
1339
1340                            if (best == Double.MinValue)
1341                            {
1342                                best = v.value;
1343                                bestpos = b;
1344                            }
1345
1346                            if (costMaster.getRelationOperator() == RelationOperator.LessThen)
1347                            {
1348                                if (v.value < best)
1349                                {
1350                                    best = v.value;
1351                                    bestpos = b;
1352                                }
1353                            }
1354                            else
1355                            {
1356                                if (v.value > best)
1357                                {
1358                                    best = v.value;
1359                                    bestpos = b;
1360                                }
1361                            }
1362                        }
1363                        tmpList.Add(valList[bestpos]);
1364                        valList.RemoveAt(bestpos);
1365
1366                    }
1367
1368                    valList = tmpList;
1369
1370
1371                    // Kinder der besten Keys erstellen
1372                    int rndInt = 0;
1373
1374                    int listSize = valList.Count;
1375                    for (int a = 0; a < 6; a++)
1376                    {
1377                        if (a % 2 == 0)
1378                        {
1379                            rndInt = (rd.Next(0, int.MaxValue)) % (keylength);
1380                            while (rndInt == 0)
1381                            {
1382                                rndInt = (rd.Next(0, int.MaxValue)) % (keylength);
1383                            }
1384                        }
1385
1386                        ValueKey parent1 = (ValueKey)valList[a];
1387                        byte[] child = new byte[parent1.keyArray.Length];
1388                        for (int b = 0; b < rndInt; b++)
1389                        {
1390                            child[b] = parent1.keyArray[b];
1391                        }
1392
1393                        int pos = rndInt;
1394                        if (a % 2 == 0)
1395                        {
1396                            ValueKey parent2 = (ValueKey)valList[a + 1];
1397                            for (int b = 0; b < parent2.keyArray.Length; b++)
1398                            {
1399                                for (int c = rndInt; c < parent1.keyArray.Length; c++)
1400                                {
1401                                    if (parent1.keyArray[c] == parent2.keyArray[b])
1402                                    {
1403                                        child[pos] = parent1.keyArray[c];
1404                                        pos++;
1405                                        break;
1406                                    }
1407                                }
1408                            }
1409                        }
1410                        else
1411                        {
1412                            ValueKey parent2 = (ValueKey)valList[a - 1];
1413                            for (int b = 0; b < parent2.keyArray.Length; b++)
1414                            {
1415                                for (int c = rndInt; c < parent1.keyArray.Length; c++)
1416                                {
1417                                    if (parent1.keyArray[c] == parent2.keyArray[b])
1418                                    {
1419                                        child[pos] = parent1.keyArray[c];
1420                                        pos++;
1421                                        break;
1422                                    }
1423                                }
1424                            }
1425                        }
1426                        int apos = (rd.Next(0, int.MaxValue)) % keylength;
1427                        int bpos = (rd.Next(0, int.MaxValue)) % keylength;
1428                        while (apos == bpos)
1429                        {
1430                            apos = (rd.Next(0, int.MaxValue)) % keylength;
1431                            bpos = (rd.Next(0, int.MaxValue)) % keylength;
1432                        }
1433                        byte tmp = child[apos];
1434                        child[apos] = child[bpos];
1435                        child[bpos] = tmp;
1436
1437                        Boolean eq = false;
1438                        foreach (ValueKey v in valList)
1439                        {
1440
1441                            if (arrayEquals(v.keyArray, child))
1442                            {
1443                                //GuiLogMessage("ZWEI GLEICHE", NotificationLevel.Debug);
1444                                ValueKey tmpValue = new ValueKey();
1445                                tmpValue.keyArray = randomArray(keylength);
1446                                byte[] dec = sender.Decrypt(input, tmpValue.keyArray, null);
1447                                double val = costMaster.calculateCost(dec);
1448
1449                                String keyStr = "";
1450                                foreach (byte bb in child)
1451                                {
1452                                    keyStr += bb + ", ";
1453                                }
1454
1455                                tmpValue.decryption = dec;
1456                                tmpValue.key = keyStr;
1457                                tmpValue.value = val;
1458                                valList.Add(tmpValue);
1459                                eq = true;
1460                                break;
1461                            }
1462                        }
1463                        if (!eq && bestOf != null)
1464                        {
1465                            foreach (ValueKey v in bestOf)
1466                            {
1467
1468                                if (arrayEquals(v.keyArray, child))
1469                                {
1470                                    //GuiLogMessage("ZWEI GLEICHE", NotificationLevel.Debug);
1471                                    ValueKey tmpValue = new ValueKey();
1472                                    tmpValue.keyArray = randomArray(keylength);
1473                                    byte[] dec = sender.Decrypt(input, tmpValue.keyArray, null);
1474                                    double val = costMaster.calculateCost(dec);
1475
1476                                    String keyStr = "";
1477                                    foreach (byte bb in child)
1478                                    {
1479                                        keyStr += bb + ", ";
1480                                    }
1481
1482                                    tmpValue.decryption = dec;
1483                                    tmpValue.key = keyStr;
1484                                    tmpValue.value = val;
1485                                    valList.Add(tmpValue);
1486                                    eq = true;
1487                                    break;
1488                                }
1489                            }
1490                        }
1491                        if (!eq)
1492                        {
1493                            ValueKey tmpValue = new ValueKey();
1494                            byte[] dec = sender.Decrypt(input, child, null);
1495                            double val = costMaster.calculateCost(dec);
1496
1497                            String keyStr = "";
1498                            foreach (byte bb in child)
1499                            {
1500                                keyStr += bb + ", ";
1501                            }
1502
1503                            tmpValue.keyArray = child;
1504                            tmpValue.decryption = dec;
1505                            tmpValue.key = keyStr;
1506                            tmpValue.value = val;
1507                            valList.Add(tmpValue);
1508                        }
1509                    }
1510
1511                    if (DateTime.Now >= lastUpdate.AddMilliseconds(1000))
1512                    {
1513                        best = Double.MinValue;
1514
1515                        if (costMaster.getRelationOperator() == RelationOperator.LessThen)
1516                        {
1517                            best = Double.MaxValue;
1518                        }
1519
1520                        list1 = getDummyLinkedList(best);
1521
1522                        if (bestOf != null)
1523                        {
1524                            foreach (ValueKey v in bestOf)
1525                            {
1526                                valuequeue.Enqueue(v);
1527                            }
1528                        }
1529
1530                        foreach (ValueKey v in valList)
1531                        {
1532                            valuequeue.Enqueue(v);
1533                        }
1534
1535                        updateToplist(list1);
1536                        showProgress(startTime, size * repeatings, it * size + iteration);
1537                        ProgressChanged(it * size + iteration, size * repeatings);
1538                        lastUpdate = DateTime.Now;
1539                    }
1540                    iteration++;
1541                }
1542                foreach (ValueKey v in valList)
1543                {
1544                    if (bestOf == null)
1545                        bestOf = new ArrayList();
1546                    bestOf.Add(v);
1547                }
1548                bestOf = updateValueKeyArrayList(bestOf, 12);
1549            }
1550        }
1551
1552        #endregion
1553
1554
1555        private ArrayList updateValueKeyArrayList(ArrayList list, int rest)
1556        {
1557            //Dummy ValueKey erstellen:
1558            ValueKey best = new ValueKey();
1559            ArrayList ret = new ArrayList();
1560
1561            // Schlechtesten x Keys löschen
1562            if (costMaster.getRelationOperator() == RelationOperator.LessThen)
1563            {
1564                for (int a = 0; a < rest; a++)
1565                {
1566                    best.value = int.MaxValue;
1567                    int pos = -1;
1568                    for (int b = 0; b < list.Count; b++)
1569                    {
1570                        ValueKey v = (ValueKey)list[b];
1571                        if (v.value < best.value)
1572                        {
1573                            best = v;
1574                            pos = b;
1575                        }
1576                    }
1577                    if (pos != -1)
1578                    {
1579                        ret.Add(list[pos]);
1580                        list.RemoveAt(pos);
1581                    }
1582                }
1583            }
1584            //costmMaster Relation Operator == Larger Than
1585            else
1586            {
1587                for (int a = 0; a < rest; a++)
1588                {
1589                    best.value = int.MinValue;
1590                    int pos = -1;
1591                    for (int b = 0; b < list.Count; b++)
1592                    {
1593                        ValueKey v = (ValueKey)list[b];
1594                        if (v.value > best.value)
1595                        {
1596                            best = v;
1597                            pos = b;
1598                        }
1599                    }
1600                    if (pos != -1)
1601                    {
1602                        ret.Add(list[pos]);
1603                        list.RemoveAt(pos);
1604                    }
1605                }
1606            }
1607            return ret;
1608        }
1609
1610        private byte[] randomArray(int length)
1611        {
1612            int[] src = new int[length];
1613            for (int i = 0; i < length; i++)
1614            {
1615                src[i] = i + 1;
1616            }
1617            if (src == null)
1618            {
1619                return null;
1620            }
1621
1622            int[] tmp = new int[src.Length];
1623
1624            int num = src.Length;
1625            int index;
1626
1627            if (rd == null) rd = new Random(System.DateTime.Now.Millisecond);
1628
1629            for (int i = 0; i < src.Length; i++)
1630            {
1631                index = (rd.Next(0, int.MaxValue)) % num;
1632                tmp[i] = src[index];
1633                src[index] = src[num - 1];
1634                num--;
1635            }
1636
1637            byte[] output = new byte[length];
1638            for (int i = 0; i < output.Length; i++)
1639            {
1640                output[i] = Convert.ToByte(tmp[i]);
1641            }
1642
1643            return output;
1644        }
1645
1646        private Boolean arrayEquals(byte[] a, byte[] b)
1647        {
1648            if (a.Length != b.Length)
1649                return false;
1650            for (int i = 0; i < a.Length; i++)
1651            {
1652                if (a[i] != b[i]) return false;
1653            }
1654            return true;
1655        }
1656
1657
1658    }
1659
1660    public struct ValueKey
1661    {
1662        public byte[] keyArray;
1663        public double value;
1664        public String key;
1665        public byte[] decryption;
1666    };
1667    public class ResultEntry
1668    {
1669        public string Ranking { get; set; }
1670        public string Value { get; set; }
1671        public string Key { get; set; }
1672        public string Text { get; set; }
1673
1674    }
1675}
Note: See TracBrowser for help on using the repository browser.