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

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

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