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

Last change on this file since 1365 was 1365, checked in by kohnen, 12 years ago

added genetic analysis to transposition analyser

File size: 43.3 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
34        TranspositionAnalyserSettings settings;
35        #region Properties
36        [PropertyInfo(Direction.InputData, "Input", "Input data for Analysis", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
37        public Byte[] Input
38        {
39            get
40            {
41                return this.input;
42            }
43
44            set
45            {
46                this.input = value;
47                OnPropertyChange("Input");
48
49            }
50        }
51
52        [PropertyInfo(Direction.InputData, "Crib", "Crib input", "Crib for Analysis", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
53        public Byte[] Crib
54        {
55            get
56            {
57                return this.crib;
58            }
59
60            set
61            {
62                this.crib = value;
63                OnPropertyChange("Crib");
64            }
65        }
66
67
68
69        #endregion
70        /// <summary>
71        /// Constructor
72        /// </summary>
73        public TranspositionAnalyser()
74        {
75            settings = new TranspositionAnalyserSettings();
76            myPresentation = new TranspositionAnalyserQuickWatchPresentation();
77            QuickWatchPresentation = myPresentation;
78            myPresentation.doppelClick += new EventHandler(this.doppelClick);
79        }
80
81        private void doppelClick(object sender, EventArgs e)
82        {
83            ListViewItem lvi = sender as ListViewItem;
84            ResultEntry rse = lvi.Content as ResultEntry;
85            Output = System.Text.Encoding.GetEncoding(1252).GetBytes(rse.Text);
86        }
87
88        private IControlEncryption controlMaster;
89        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.None, null)]
90        public IControlEncryption ControlMaster
91        {
92
93            get { return controlMaster; }
94            set
95            {
96                // value.OnStatusChanged += onStatusChanged;
97                controlMaster = value;
98                OnPropertyChanged("ControlMaster");
99
100            }
101        }
102
103        private IControlCost costMaster;
104        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.None, null)]
105        public IControlCost CostMaster
106        {
107            get { return costMaster; }
108            set
109            {
110                costMaster = value;
111            }
112        }
113
114        private byte[] output;
115        [PropertyInfo(Direction.OutputData, "Output", "output", "", DisplayLevel.Beginner)]
116        public byte[] Output
117        {
118            get
119            {
120                return this.output;
121            }
122            set
123            {
124                this.output = value;
125                OnPropertyChanged("Output");
126            }
127        }
128
129        public void GuiLogMessage(string message, NotificationLevel loglevel)
130        {
131            if (OnGuiLogNotificationOccured != null)
132                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
133        }
134
135        #region IPlugin Member
136
137        public event Cryptool.PluginBase.StatusChangedEventHandler OnPluginStatusChanged;
138
139        public event Cryptool.PluginBase.GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
140
141        public event Cryptool.PluginBase.PluginProgressChangedEventHandler OnPluginProgressChanged;
142
143        public ISettings Settings
144        {
145            get { return settings; }
146        }
147
148
149
150        public UserControl Presentation
151        {
152            get { return null; }
153        }
154
155        public UserControl QuickWatchPresentation
156        {
157            get;
158            private set;
159        }
160
161        public void PreExecution()
162        {
163
164        }
165
166        public void Execute()
167        {
168
169
170            if (this.input != null)
171            {
172                if (this.ControlMaster != null && this.input != null)
173                    this.process(this.ControlMaster);
174                else
175                {
176                    GuiLogMessage("You have to connect the Transposition Plugin to the Transpostion Analyzer Control!", NotificationLevel.Warning);
177                }
178            }
179            ProgressChanged(1, 1);
180        }
181
182        public void PostExecution()
183        {
184
185        }
186
187        public void Pause()
188        {
189
190        }
191
192        private Boolean stop;
193        public void Stop()
194        {
195            stop = true;
196        }
197
198        public void Initialize()
199        {
200            this.settings.Analysis_method = 0;
201        }
202
203        public void Dispose()
204        {
205
206        }
207
208        private void onStatusChanged(IControl sender, bool readyForExecution)
209        {
210
211        }
212
213        public void OnPropertyChanged(string name)
214        {
215            if (PropertyChanged != null)
216            {
217                PropertyChanged(this, new PropertyChangedEventArgs(name));
218            }
219        }
220
221        private void OnPropertyChange(String propertyname)
222        {
223            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(propertyname));
224        }
225
226        public void process(IControlEncryption sender)
227        {
228            if (input != null)
229            {
230                switch (this.settings.Analysis_method)
231                {
232                    case 0: Output = costfunction_bruteforce(sender); GuiLogMessage("Starting Brute-Force Analysis", NotificationLevel.Info); break;
233                    case 1: GuiLogMessage("Starting Analysis with crib", NotificationLevel.Info); cribAnalysis(this.crib, this.input); break;
234                    case 2: GuiLogMessage("Starting genetic analysis", NotificationLevel.Info); geneticAnalysis(sender); break;
235                }
236            }
237            else
238            {
239                GuiLogMessage("No Input!", NotificationLevel.Error);
240            }
241
242
243        }
244
245        private int[] getBruteforceSettings()
246        {
247            int[] set;
248            int sum = 0;
249            if (settings.ColumnColumnColumn) sum++;
250            if (settings.ColumnColumnRow) sum++;
251            if (settings.RowColumnColumn) sum++;
252            if (settings.RowColumnRow) sum++;
253
254            if (sum > 0)
255            {
256                set = new int[sum];
257                int count = 0;
258                if (settings.ColumnColumnColumn)
259                {
260                    set[count] = 0;
261                    count++;
262                }
263                if (settings.ColumnColumnRow)
264                {
265                    set[count] = 1;
266                    count++;
267                }
268                if (settings.RowColumnColumn)
269                {
270                    set[count] = 2;
271                    count++;
272                }
273
274                if (settings.RowColumnRow)
275                {
276                    set[count] = 3;
277                    count++;
278                }
279                return set;
280            }
281            else
282            {
283                return null;
284            }
285
286        }
287
288        private byte[] costfunction_bruteforce(IControlEncryption sender)
289        {
290            valuequeue = Queue.Synchronized(new Queue());
291            int[] set = getBruteforceSettings();
292            stop = false;
293            if (sender != null && costMaster != null && set != null)
294            {
295                GuiLogMessage("start", NotificationLevel.Info);
296                double best = Double.MinValue;
297
298                if (costMaster.getRelationOperator() == RelationOperator.LessThen)
299                {
300                    best = Double.MaxValue;
301                }
302
303                list1 = getDummyLinkedList(best);
304                String best_text = "";
305                ArrayList list = null;
306
307               
308                //Just for fractional-calculation:
309                PermutationGenerator per = new PermutationGenerator(2);
310                DateTime starttime = DateTime.Now;
311                DateTime lastUpdate = DateTime.Now;
312
313                int max = 0;
314                max = settings.MaxLength;
315                //GuiLogMessage("Max: " + max, NotificationLevel.Info);
316                if (max > 1 && max < 21)
317                {
318                    long size = 0;
319                    for (int i = 2; i <= max; i++)
320                    {
321                        size = size + per.getFactorial(i);
322                    }
323                    size = size * set.Length;
324                    long sum = 0;
325                    for (int i = 1; i <= max; i++)
326                    {
327                        // for every selected bruteforce mode:
328                        for (int s = 0; s < set.Length; s++)
329                        {
330                            switch (set[s])
331                            {
332                                case (0):
333                                    controlMaster.changeSettings("ReadIn", ReadInMode.byColumn);
334                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
335                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byColumn);
336                                    break;
337                                case (1):
338                                    controlMaster.changeSettings("ReadIn", ReadInMode.byColumn);
339                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
340                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byRow);
341                                    break;
342                                case (2):
343                                    controlMaster.changeSettings("ReadIn", ReadInMode.byRow);
344                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
345                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byColumn);
346                                    break;
347                                case (3):
348                                    controlMaster.changeSettings("ReadIn", ReadInMode.byRow);
349                                    controlMaster.changeSettings("Permute", PermutationMode.byColumn);
350                                    controlMaster.changeSettings("ReadOut", ReadOutMode.byRow);
351                                    break;
352                            }
353
354                            per = new PermutationGenerator(i);
355
356                            while (per.hasMore() && !stop)
357                            {
358                                best = list1.Last.Value.value;
359                                int[] key = per.getNext();
360                                byte[] b = new byte[key.Length];
361                                for (int j = 0; j < b.Length; j++)
362                                {
363                                    b[j] = Convert.ToByte(key[j]);
364                                }
365                                byte[] dec = sender.Decrypt(input, b, null);
366                                if (dec != null)
367                                {
368                                    double val = costMaster.calculateCost(dec);
369                                    if (val.Equals(new Double()))
370                                    {
371                                        return new byte[0];
372                                    }
373                                    if (costMaster.getRelationOperator() == RelationOperator.LessThen)
374                                    {
375                                        if (val <= best)
376                                        {
377                                            ValueKey valkey = new ValueKey();
378                                            String keyStr = "";
379                                            foreach (int xyz in key)
380                                            {
381                                                keyStr += xyz +", ";
382                                            }
383                                            valkey.decryption = dec;
384                                            valkey.key = keyStr;
385                                            valkey.value = val;
386                                            valuequeue.Enqueue(valkey);
387                                        }
388                                    }
389                                    else
390                                    {
391                                        if (val >= best)
392                                        {
393                                            ValueKey valkey = new ValueKey();
394                                            String keyStr = "";
395                                            foreach (int xyz in key)
396                                            {
397                                                keyStr += xyz;
398                                            }
399                                            valkey.decryption = dec;
400                                            valkey.key = keyStr;
401                                            valkey.value = val;
402                                            valuequeue.Enqueue(valkey);
403                                        }
404                                    }
405                                }
406
407                                sum++;
408                                if (DateTime.Now >= lastUpdate.AddMilliseconds(1000))
409                                {
410                                    updateToplist(list1);
411                                    showProgress(starttime, size, sum);
412                                    ProgressChanged(sum, size);
413                                    lastUpdate = DateTime.Now;
414                                }
415                            }
416                        }
417                    }
418                    if (list != null)
419                    {
420                        int i = 1;
421                        foreach (string tmp in list)
422                        {
423                            GuiLogMessage("ENDE (" + i++ + ")" + best + ": " + tmp, NotificationLevel.Info);
424                        }
425                    }
426                    else
427                    {
428                        GuiLogMessage("ENDE " + best + ": " + best_text, NotificationLevel.Info);
429                    }
430                    return list1.First.Value.decryption;
431                }
432                else
433                {
434                    GuiLogMessage("Error: Check transposition bruteforce length. Max length is 20!", NotificationLevel.Error);
435                    return null;
436                }
437            }
438            else
439            {
440                GuiLogMessage("Error: No costfunction applied.", NotificationLevel.Error);
441                return null;
442            }
443        }
444
445        private LinkedList<ValueKey> getDummyLinkedList(double best)
446        {
447            ValueKey valueKey = new ValueKey();
448            valueKey.value = best;
449            valueKey.key = "dummykey";
450            valueKey.decryption = new byte[0];
451            LinkedList<ValueKey> list = new LinkedList<ValueKey>();
452            LinkedListNode<ValueKey> node = list.AddFirst(valueKey);
453            for (int i = 0; i < 9; i++)
454            {
455                node = list.AddAfter(node, valueKey);
456            }
457            return list;
458        }
459
460        private void updateToplist(LinkedList<ValueKey> costList)
461        {
462            LinkedListNode<ValueKey> node;
463            while (valuequeue.Count != 0)
464            {
465                ValueKey vk = (ValueKey)valuequeue.Dequeue();
466                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
467                {
468                    if (vk.value > costList.Last().value)
469                    {
470                        node = costList.First;
471                        int i = 0;
472                        while (node != null)
473                        {
474                            if (vk.value > node.Value.value)
475                            {
476                                costList.AddBefore(node, vk);
477                                costList.RemoveLast();
478                                if (i == 0)
479                                {
480                                    Output = vk.decryption;
481                                }
482                                // value_threshold = costList.Last.Value.value;
483                                break;
484                            }
485                            node = node.Next;
486                            i++;
487                        }//end while
488                    }//end if
489                }
490                else
491                {
492                    if (vk.value < costList.Last().value)
493                    {
494                        node = costList.First;
495                        int i = 0;
496                        while (node != null)
497                        {
498                            if (vk.value < node.Value.value)
499                            {
500                                costList.AddBefore(node, vk);
501                                costList.RemoveLast();
502                                if (i == 0)
503                                {
504                                    Output = vk.decryption;
505                                }
506
507                                // value_threshold = costList.Last.Value.value;
508                                break;
509                            }
510                            node = node.Next;
511                            i++;
512                        }//end while
513                    }//end if
514                }
515            }
516        }
517
518        #endregion
519
520        #region INotifyPropertyChanged Member
521
522        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
523
524        #endregion
525
526        public void ProgressChanged(double value, double max)
527        {
528            if (OnPluginProgressChanged != null)
529            {
530                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
531
532            }
533        }
534
535        #region cribAnalysis
536        public void cribAnalysis(byte[] crib, byte[] cipher)
537        {
538
539            if (crib != null && crib != null)
540            {
541                foreach (int c in getKeyLength(crib, cipher))
542                {
543                    GuiLogMessage("Possible Key-Length: " + c, NotificationLevel.Info);
544                }
545            }
546            else { GuiLogMessage("Missing crib or input!", NotificationLevel.Info); }
547        }
548
549        #endregion
550
551        #region
552
553        public ArrayList getKeyLength(byte[] crib, byte[] cipher)
554        {
555
556            ArrayList keylengths = new ArrayList();
557
558            for (int i = 1; i < crib.Length; i++)
559            {
560                byte[,] cipherM = cipherToMatrix(i, cipher);
561                byte[,] cribM = cribToMatrix(i, crib);
562                int[] analysed = analyse(i, cipherM, cribM);
563
564                for (int j = 0; j < analysed.Length; j++)
565                {
566
567                    if (analysed[j] != 0)
568                    {
569                        if (j == analysed.Length - 1)
570                        {
571                            keylengths.Add(i);
572                        }
573                    }
574                    else break;
575                }
576
577            }
578            return keylengths;
579
580        }
581
582        byte[,] cribToMatrix(int i, byte[] tmp)
583        {
584            int x = tmp.Length / i;
585            if (tmp.Length % i != 0)
586            {
587                x++;
588            }
589            byte[,] arr = new byte[i, x];
590            int count = 0;
591
592            for (int a = 0; a < x; a++)
593            {
594                for (int b = 0; b < i; b++)
595                {
596                    if (count < tmp.Length)
597                        arr[b, a] = tmp[count++];
598                }
599            }
600            return arr;
601        }
602
603        byte[,] cipherToMatrix(int i, byte[] tmp)
604        {
605            int length = tmp.Length / i;
606            int off = 0;
607            if (tmp.Length % i != 0)
608            {
609                length++;
610                off = (i * length) - tmp.Length;
611            }
612            byte[,] cipherMatrix = new byte[length, i];
613            int pos = 0;
614
615            for (int a = 0; a < i; a++)
616            {
617                for (int b = 0; b < length; b++)
618                {
619                    if (b == length - 1)
620                    {
621                        if (a < off)
622                        {
623                            break;
624                        }
625                    }
626                    cipherMatrix[b, a] = tmp[pos];
627                    pos++;
628                }
629            }
630            return cipherMatrix;
631        }
632
633        int[] analyse(int i, byte[,] cipherMatrix, byte[,] cribMatrix)
634        {
635            int cipherMatrixLength = cipherMatrix.Length / i;
636            int cribMatrixHeight = cribMatrix.Length / i;
637            int[] poscount = new int[i];
638            ArrayList[] def = new ArrayList[i];
639            for (int a = 0; a < i; a++)
640            {
641                def[a] = new ArrayList();
642            }
643
644            byte newchar = new byte();
645            byte emptychar = new byte();
646            int count = 0;
647            for (int a = 0; a < i; a++)
648            {
649                if (!cribMatrix[a, cribMatrixHeight - 1].Equals(emptychar))
650                {
651                    count++;
652                }
653                else
654                {
655                    poscount[a] = -1;
656                }
657            }
658
659            for (int x = 0; x < count; x++)
660            {
661                for (int a = 0; a < i; a++)
662                {
663                    for (int b = 0; b < cipherMatrixLength; b++)
664                    {
665                        if (cribMatrix[x, 0].Equals(cipherMatrix[b, a]))
666                        {
667                            int tmpA = a;
668                            int tmpB = b;
669
670                            for (int y = 1; y < cribMatrixHeight; y++)
671                            {
672                                tmpB++;
673                                if (tmpB == cipherMatrixLength - 1)
674                                {
675                                    if (cipherMatrix[tmpB, tmpA].Equals(newchar))
676                                    {
677                                        tmpB = 0;
678                                        tmpA++;
679                                    }
680                                }
681
682                                if ((tmpB) < cipherMatrixLength)
683                                {
684                                    if (cribMatrix[x, y].Equals(cipherMatrix[tmpB, tmpA]))
685                                    {
686                                        if (y.Equals(cribMatrixHeight - 1))
687                                        {
688                                            poscount[x]++;
689                                            def[x].Add(b);
690
691                                        }
692                                    }
693                                    else
694                                    {
695                                        break;
696                                    }
697                                }
698                            }
699                        }
700                    }
701                }
702            }
703            return poscount;
704        }
705
706        #endregion
707
708        private void showProgress(DateTime startTime, long size, long sum)
709        {
710            LinkedListNode<ValueKey> linkedListNode;
711            if (QuickWatchPresentation.IsVisible && !stop)
712            {
713                DateTime currentTime = DateTime.Now;
714                TimeSpan span = currentTime.Subtract(startTime);
715                int seconds = span.Seconds;
716                int minutes = span.Minutes;
717                int hours = span.Hours;
718                int days = span.Days;
719
720                long allseconds = seconds + 60 * minutes + 60 * 60 * hours + 24 * 60 * 60 * days;
721                if (allseconds == 0) allseconds = 1;
722                long keysPerSec = sum / allseconds;
723
724                long keystodo = (size - sum);
725               
726                long secstodo = keystodo / keysPerSec;
727
728                //dummy Time
729                DateTime endTime = new DateTime(1970, 1, 1);
730                try
731                {
732                    endTime = DateTime.Now.AddSeconds(secstodo);
733                }
734                catch
735                {
736
737                }
738
739
740                ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
741                {
742
743                    ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Text = "" + keysPerSec;
744
745                    if (endTime != (new DateTime(1970, 1, 1)))
746                    {
747                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "" + endTime.Subtract(DateTime.Now);
748
749                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "" + endTime;
750                    }
751                    else
752                    {
753                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "incalculable";
754
755                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
756                    }
757                    if (list1 != null)
758                    {
759                        linkedListNode = list1.First;
760                        ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).entries.Clear();
761                        int i = 0;
762                        while (linkedListNode != null)
763                        {
764                            i++;
765                            ResultEntry entry = new ResultEntry();
766                            entry.Ranking = i.ToString();
767
768
769                            String dec = System.Text.Encoding.ASCII.GetString(linkedListNode.Value.decryption);
770                            if (dec.Length > 2500) // Short strings need not to be cut off
771                            {
772                                dec = dec.Substring(0, 2500);
773                            }
774                            entry.Text = dec;
775                            entry.Key = linkedListNode.Value.key;
776                            entry.Value = Math.Round(linkedListNode.Value.value, 2) + "";
777
778
779                            ((TranspositionAnalyserQuickWatchPresentation)QuickWatchPresentation).entries.Add(entry);
780
781                            linkedListNode = linkedListNode.Next;
782                        }
783
784                    }
785                }
786
787
788                , null);
789
790            }
791        }
792
793        private void geneticAnalysis(IControlEncryption sender)
794        {
795            stop = false;
796
797            valuequeue = Queue.Synchronized(new Queue());
798           
799            int size = settings.Iterations;
800            int keylength = settings.KeySize;
801            int repeatings = settings.Repeatings;
802
803            if (size < 2 || keylength < 2 || repeatings <1)
804            {
805                GuiLogMessage("Check keylength and iterations", NotificationLevel.Error);
806                return;
807            }
808
809            if (sender == null || costMaster == null || input == null)
810            {
811                if (sender == null)
812                {
813                    GuiLogMessage("sender == null", NotificationLevel.Error);
814                }
815                if (costMaster == null)
816                {
817                    GuiLogMessage("costMaster == null", NotificationLevel.Error);
818                }
819                if (input == null)
820                {
821                    GuiLogMessage("input == null", NotificationLevel.Error);
822                }
823                return;
824            }
825            DateTime startTime = DateTime.Now;
826            DateTime lastUpdate = DateTime.Now;
827
828            ArrayList bestOf = null;
829
830            for (int it = 0; it < repeatings; it++)
831            {
832
833                ArrayList valList = new ArrayList();
834
835                for (int i = 0; i < 12; i++)
836                {
837                    byte[] rndkey = randomArray(keylength);
838                    byte[] dec = sender.Decrypt(input, rndkey, null);
839                    double val = costMaster.calculateCost(dec);
840
841                    String keyStr = "";
842                    foreach (byte tmp in rndkey)
843                    {
844                        keyStr += tmp + ", ";
845                    }
846
847
848                    ValueKey v = new ValueKey();
849                    v.decryption = dec;
850                    v.key = keyStr;
851                    v.keyArray = rndkey;
852                    v.value = val;
853                    valList.Add(v);
854                }
855
856                valuequeue = Queue.Synchronized(new Queue());
857
858
859                int iteration = 0;
860                while (iteration < size && !stop)
861                {
862                    //Dummy ValueKey erstellen:
863                    ValueKey highest = new ValueKey();
864
865                    // Schlechtesten 6 Keys löschen
866                    if (costMaster.getRelationOperator() == RelationOperator.LessThen)
867                    {
868                        for (int a = 0; a < 6; a++)
869                        {
870                            highest.value = int.MinValue;
871                            int pos = -1;
872                            for (int b = 0; b < valList.Count; b++)
873                            {
874                                ValueKey v = (ValueKey)valList[b];
875                                if (v.value > highest.value)
876                                {
877                                    highest = v;
878                                    pos = b;
879                                }
880                            }
881                            if (pos != -1)
882                            {
883                                valList.RemoveAt(pos);
884                            }
885                        }
886                    }
887                    //costmMaster Relation Operator == Larger Than
888                    else
889                    {
890                        for (int a = 0; a < 6; a++)
891                        {
892                            highest.value = int.MaxValue;
893                            int pos = -1;
894                            for (int b = 0; b < valList.Count; b++)
895                            {
896                                ValueKey v = (ValueKey)valList[b];
897                                if (v.value < highest.value)
898                                {
899                                    highest = v;
900                                    pos = b;
901                                }
902                            }
903                            if (pos != -1)
904                            {
905                                valList.RemoveAt(pos);
906                            }
907                        }
908                    }
909
910                    //valListe sortieren
911                    ArrayList tmpList = new ArrayList(6);
912
913                    double best = Double.MinValue;
914                    int bestpos = -1;
915                    for (int a = 0; a < 6; a++)
916                    {
917                        best = Double.MinValue;
918                        bestpos = -1;
919
920                        for (int b = 0; b < valList.Count; b++)
921                        {
922                            ValueKey v = (ValueKey)valList[b];
923
924                            if (best == Double.MinValue)
925                            {
926                                best = v.value;
927                                bestpos = b;
928                            }
929
930                            if (costMaster.getRelationOperator() == RelationOperator.LessThen)
931                            {
932                                if (v.value < best)
933                                {
934                                    best = v.value;
935                                    bestpos = b;
936                                }
937                            }
938                            else
939                            {
940                                if (v.value > best)
941                                {
942                                    best = v.value;
943                                    bestpos = b;
944                                }
945                            }
946                        }
947                        tmpList.Add(valList[bestpos]);
948                        valList.RemoveAt(bestpos);
949
950                    }
951
952                    valList = tmpList;
953
954
955                    // Kinder der besten Keys erstellen
956                    int rndInt = 0;
957
958                    int listSize = valList.Count;
959                    for (int a = 0; a < 6; a++)
960                    {
961                        if (a % 2 == 0)
962                        {
963                            rndInt = (rd.Next(0, int.MaxValue)) % (keylength);
964                            while (rndInt == 0)
965                            {
966                                rndInt = (rd.Next(0, int.MaxValue)) % (keylength);
967                            }
968                        }
969
970                        ValueKey parent1 = (ValueKey)valList[a];
971                        byte[] child = new byte[parent1.keyArray.Length];
972                        for (int b = 0; b < rndInt; b++)
973                        {
974                            child[b] = parent1.keyArray[b];
975                        }
976
977                        int pos = rndInt;
978                        if (a % 2 == 0)
979                        {
980                            ValueKey parent2 = (ValueKey)valList[a + 1];
981                            for (int b = 0; b < parent2.keyArray.Length; b++)
982                            {
983                                for (int c = rndInt; c < parent1.keyArray.Length; c++)
984                                {
985                                    if (parent1.keyArray[c] == parent2.keyArray[b])
986                                    {
987                                        child[pos] = parent1.keyArray[c];
988                                        pos++;
989                                        break;
990                                    }
991                                }
992                            }
993                        }
994                        else
995                        {
996                            ValueKey parent2 = (ValueKey)valList[a - 1];
997                            for (int b = 0; b < parent2.keyArray.Length; b++)
998                            {
999                                for (int c = rndInt; c < parent1.keyArray.Length; c++)
1000                                {
1001                                    if (parent1.keyArray[c] == parent2.keyArray[b])
1002                                    {
1003                                        child[pos] = parent1.keyArray[c];
1004                                        pos++;
1005                                        break;
1006                                    }
1007                                }
1008                            }
1009                        }
1010                        int apos = (rd.Next(0, int.MaxValue)) % keylength;
1011                        int bpos = (rd.Next(0, int.MaxValue)) % keylength;
1012                        while (apos == bpos)
1013                        {
1014                            apos = (rd.Next(0, int.MaxValue)) % keylength;
1015                            bpos = (rd.Next(0, int.MaxValue)) % keylength;
1016                        }
1017                        byte tmp = child[apos];
1018                        child[apos] = child[bpos];
1019                        child[bpos] = tmp;
1020
1021                        Boolean eq = false;
1022                        foreach (ValueKey v in valList)
1023                        {
1024
1025                            if (arrayEquals(v.keyArray, child))
1026                            {
1027                                //GuiLogMessage("ZWEI GLEICHE", NotificationLevel.Debug);
1028                                ValueKey tmpValue = new ValueKey();
1029                                tmpValue.keyArray = randomArray(keylength);
1030                                byte[] dec = sender.Decrypt(input, tmpValue.keyArray, null);
1031                                double val = costMaster.calculateCost(dec);
1032
1033                                String keyStr = "";
1034                                foreach (byte bb in child)
1035                                {
1036                                    keyStr += bb + ", ";
1037                                }
1038
1039                                tmpValue.decryption = dec;
1040                                tmpValue.key = keyStr;
1041                                tmpValue.value = val;
1042                                valList.Add(tmpValue);
1043                                eq = true;
1044                                break;
1045                            }
1046                        }
1047                        if (!eq && bestOf != null)
1048                        {
1049                            foreach (ValueKey v in bestOf)
1050                            {
1051
1052                                if (arrayEquals(v.keyArray, child))
1053                                {
1054                                    //GuiLogMessage("ZWEI GLEICHE", NotificationLevel.Debug);
1055                                    ValueKey tmpValue = new ValueKey();
1056                                    tmpValue.keyArray = randomArray(keylength);
1057                                    byte[] dec = sender.Decrypt(input, tmpValue.keyArray, null);
1058                                    double val = costMaster.calculateCost(dec);
1059
1060                                    String keyStr = "";
1061                                    foreach (byte bb in child)
1062                                    {
1063                                        keyStr += bb + ", ";
1064                                    }
1065
1066                                    tmpValue.decryption = dec;
1067                                    tmpValue.key = keyStr;
1068                                    tmpValue.value = val;
1069                                    valList.Add(tmpValue);
1070                                    eq = true;
1071                                    break;
1072                                }
1073                            }
1074                        }
1075                        if (!eq)
1076                        {
1077                            ValueKey tmpValue = new ValueKey();
1078                            byte[] dec = sender.Decrypt(input, child, null);
1079                            double val = costMaster.calculateCost(dec);
1080
1081                            String keyStr = "";
1082                            foreach (byte bb in child)
1083                            {
1084                                keyStr += bb + ", ";
1085                            }
1086
1087                            tmpValue.keyArray = child;
1088                            tmpValue.decryption = dec;
1089                            tmpValue.key = keyStr;
1090                            tmpValue.value = val;
1091                            valList.Add(tmpValue);
1092                        }
1093                    }
1094
1095                    if (DateTime.Now >= lastUpdate.AddMilliseconds(1000))
1096                    {
1097                        best = Double.MinValue;
1098
1099                        if (costMaster.getRelationOperator() == RelationOperator.LessThen)
1100                        {
1101                            best = Double.MaxValue;
1102                        }
1103
1104                        list1 = getDummyLinkedList(best);
1105
1106                        if (bestOf != null)
1107                        {
1108                            foreach (ValueKey v in bestOf)
1109                            {
1110                                valuequeue.Enqueue(v);
1111                            }
1112                        }
1113
1114                        foreach (ValueKey v in valList)
1115                        {
1116                            valuequeue.Enqueue(v);
1117                        }
1118                        updateToplist(list1);
1119                        showProgress(startTime, size * repeatings, it * size + iteration);
1120                        ProgressChanged(it*size+ iteration, size*repeatings);
1121                        lastUpdate = DateTime.Now;
1122                    }
1123                    iteration++;
1124                }
1125                foreach (ValueKey v in valList)
1126                {
1127                    if (bestOf == null)
1128                        bestOf = new ArrayList();
1129                    bestOf.Add(v);
1130                }
1131            }
1132        }
1133
1134        private byte[] randomArray(int length)
1135        {
1136            int[] src = new int[length];
1137            for (int i = 0; i < length; i++)
1138            {
1139                src[i] = i + 1;
1140            }
1141            if (src == null)
1142            {
1143                return null;
1144            }
1145
1146            int[] tmp = new int[src.Length];
1147
1148            int num = src.Length;
1149            int index;
1150
1151            if (rd == null) rd = new Random(System.DateTime.Now.Millisecond);
1152
1153            for (int i = 0; i < src.Length; i++)
1154            {
1155                index = (rd.Next(0, int.MaxValue)) % num;
1156                tmp[i] = src[index];
1157                src[index] = src[num - 1];
1158                num--;
1159            }
1160
1161            byte[] output = new byte[length];
1162            for (int i = 0; i < output.Length; i++)
1163            {
1164                output[i] = Convert.ToByte(tmp[i]);
1165            }
1166            return output;
1167        }
1168
1169        private Boolean arrayEquals(byte[] a, byte[] b)
1170        {
1171            if (a.Length != b.Length)
1172                return false;
1173            for (int i = 0; i < a.Length; i++)
1174            {
1175                if (a[i] != b[i]) return false;
1176            }
1177            return true;
1178        }
1179
1180
1181    }
1182
1183    public struct ValueKey
1184    {
1185        public byte[] keyArray;
1186        public double value;
1187        public String key;
1188        public byte[] decryption;
1189    };
1190    public class ResultEntry
1191    {
1192        public string Ranking { get; set; }
1193        public string Value { get; set; }
1194        public string Key { get; set; }
1195        public string Text { get; set; }
1196
1197    }
1198
1199}
Note: See TracBrowser for help on using the repository browser.