source: trunk/CrypPlugins/KeySearcher/KeySearcher.cs @ 1083

Last change on this file since 1083 was 1083, checked in by arnold, 12 years ago

Changed KeySearcher-IControl-stuff (Ticket 131)

File size: 32.1 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 System.Collections;
10using System.Collections.Generic;
11using System.Threading;
12using System.Windows.Threading;
13using Cryptool.PluginBase.Miscellaneous;
14using System.IO;
15using Cryptool.PluginBase.IO;
16
17namespace KeySearcher
18{   
19    [Author("Sven Rech, Nils Kopal, Raoul Falk, Dennis Nolte", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
20    [PluginInfo(true, "KeySearcher", "Bruteforces a decryption algorithm.", "KeySearcher/DetailedDescription/Description.xaml", "KeySearcher/Images/icon.png")]
21    public class KeySearcher : IAnalysisMisc
22    {
23        /// <summary>
24        /// used for creating the TopList
25        /// </summary>
26        private Queue valuequeue;
27        private double value_threshold;
28        /// <summary>
29        /// the thread with the most keys left
30        /// </summary>
31        private int maxThread;
32        private Mutex maxThreadMutex = new Mutex();
33
34        private KeyPattern pattern = null;
35        public KeyPattern Pattern
36        {
37            get
38            {
39                return pattern;
40            }
41            set
42            {
43                pattern = value;
44                if ((settings.Key == null) || ((settings.Key != null) && !pattern.testWildcardKey(settings.Key)))
45                    settings.Key = pattern.giveInputPattern();
46            }
47        }
48
49        private bool stop;
50
51        #region IControlEncryption + IControlCost + InputFields
52
53        #region IControlEncryption Members
54
55        private IControlEncryption controlMaster;
56        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
57        public IControlEncryption ControlMaster
58        {
59            get { return controlMaster; }
60            set
61            {
62                if (controlMaster != null)
63                {
64                    controlMaster.keyPatternChanged -= keyPatternChanged;
65                    controlMaster.OnStatusChanged -= onStatusChanged;
66                }
67                if (value != null)
68                {
69                    Pattern = new KeyPattern(value.getKeyPattern());
70                    value.keyPatternChanged += keyPatternChanged;
71                    value.OnStatusChanged += onStatusChanged;
72                    controlMaster = value;
73                    OnPropertyChanged("ControlMaster");
74
75                }
76                else
77                    controlMaster = null;
78            }
79        }
80
81        #endregion
82
83        #region IControlCost Members
84
85        private IControlCost costMaster;
86        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
87        public IControlCost CostMaster
88        {
89            get { return costMaster; }
90            set
91            {
92                costMaster = value;
93            }
94        }
95
96        #endregion
97
98        /* BEGIN: following lines are from Arnie - 2010.01.12 */
99        CryptoolStream decryptedData;
100        [PropertyInfo(Direction.InputData,"Encrypted Data","Encrypted data out of an Encryption PlugIn","",true,false,DisplayLevel.Beginner,QuickWatchFormat.Hex,"")]
101        public CryptoolStream DecryptedData
102        {
103            get { return this.decryptedData; }
104            set
105            {
106                if (value != this.decryptedData)
107                {
108                    this.decryptedData = value;
109                    cryptoolStreamChanged = true;
110                    OnPropertyChanged("EncryptedData");
111                }
112            }
113        }
114
115        /// <summary>
116        /// When the Input-Slot changed, set this variable to true, so the new Stream will be transformed to byte[]
117        /// </summary>
118        private bool cryptoolStreamChanged = false;
119        private byte[] decryptedByteData;
120        private byte[] GetByteFromCryptoolStream(CryptoolStream cryptoolStream)
121        {
122            // only transform CryptoolStream to Byte[], if there is a new CryptoolStream
123            // or decryptedByteData is Null
124            if (cryptoolStreamChanged || decryptedByteData == null)
125            {
126                CryptoolStream cs = new CryptoolStream();
127                cs.OpenRead(cryptoolStream.FileName);
128                decryptedByteData = new byte[cs.Length];
129                if(cs.Length > Int32.MaxValue)
130                    throw(new Exception("CryptoolStream length is longer than the Int32.MaxValue"));
131                cs.Read(decryptedByteData, 0, (int)cs.Length);
132            }
133            return decryptedByteData;
134        }
135
136        byte[] initVector;
137        [PropertyInfo(Direction.InputData, "Initialization Vector", "Initialization vector with which the data were encrypted", "", DisplayLevel.Beginner)]
138        public byte[] InitVector
139        {
140            get { return this.initVector; }
141            set
142            {
143                if (value != this.initVector)
144                {
145                    this.initVector = value;
146                    OnPropertyChanged("InitVector");
147                }
148            }
149        }
150        /* END: Lines above are from Arnie - 2010.01.12 */
151
152        #endregion
153
154        #region IPlugin Members
155
156        public event StatusChangedEventHandler OnPluginStatusChanged;
157
158        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
159
160        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
161
162        private KeySearcherSettings settings;
163
164        public KeySearcher()
165        {
166            settings = new KeySearcherSettings(this);
167            QuickWatchPresentation = new KeySearcherQuickWatchPresentation();
168           
169        }
170
171        public ISettings Settings
172        {
173            get { return settings; }
174        }
175
176        public UserControl Presentation
177        {
178            get { return QuickWatchPresentation; }
179        }
180
181        public UserControl QuickWatchPresentation
182        {
183            get;
184            private set;
185        }
186
187        public void PreExecution()
188        {
189        }
190
191        // because Encryption PlugIns were changed radical, the new StartPoint is here - Arnie 2010.01.12
192        public void Execute()
193        {
194            if (this.DecryptedData != null) //to prevent execution on initialization
195            {
196                if (this.ControlMaster != null)
197                    this.process(this.ControlMaster);
198                else
199                {
200                    GuiLogMessage("You have to connect the KeySearcher with the Decryption Control!", NotificationLevel.Warning);
201                }
202            }
203        }
204
205        public void PostExecution()
206        {
207        }
208
209        public void Pause()
210        {
211        }
212
213        public void Stop()
214        {
215            stop = true;
216        }
217
218        public void Initialize()
219        {
220        }
221
222        public void Dispose()
223        {
224        }
225
226        #endregion
227
228        #region INotifyPropertyChanged Members
229
230        public event PropertyChangedEventHandler PropertyChanged;
231
232        public void OnPropertyChanged(string name)
233        {
234            if (PropertyChanged != null)
235            {
236                PropertyChanged(this, new PropertyChangedEventArgs(name));
237            }
238        }
239
240        #endregion
241
242        /* BEGIN functionality */
243
244        #region whole KeySearcher functionality
245
246        private class ThreadStackElement
247        {
248            public AutoResetEvent ev;
249            public int threadid;
250        }
251
252        #region code for the worker threads
253
254        private void KeySearcherJob(object param)
255        {
256            object[] parameters = (object[])param;
257            KeyPattern[] patterns = (KeyPattern[])parameters[0];
258            int threadid = (int)parameters[1];
259            BigInteger[] doneKeysArray = (BigInteger[])parameters[2];
260            BigInteger[] keycounterArray = (BigInteger[])parameters[3];
261            BigInteger[] keysLeft = (BigInteger[])parameters[4];
262            IControlEncryption sender = (IControlEncryption)parameters[5];
263            int bytesToUse = (int)parameters[6];
264            Stack threadStack = (Stack)parameters[7];
265
266            KeyPattern pattern = patterns[threadid];
267
268            bool useKeyblocks = true;
269
270            try
271            {
272                while (pattern != null)
273                {
274                    BigInteger size = pattern.size();
275                    keysLeft[threadid] = size;
276                    int nextWildcard;
277
278                    do
279                    {
280                        //if we are the thread with most keys left, we have to share them:
281                        if (maxThread == threadid && threadStack.Count != 0)
282                        {
283                            maxThreadMutex.WaitOne();
284                            if (maxThread == threadid && threadStack.Count != 0)
285                            {
286                                try
287                                {
288                                    KeyPattern[] split = pattern.split();
289                                    patterns[threadid] = split[0];
290                                    pattern = split[0];
291                                    ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
292                                    patterns[elem.threadid] = split[1];
293                                    elem.ev.Set();    //wake the other thread up                                   
294                                    size = pattern.size();
295                                    keysLeft[threadid] = size;
296                                }
297                                catch (Exception e)
298                                {
299                                    //pattern can't be split? who cares :)
300                                }
301                                maxThread = -1;
302                            }
303                            maxThreadMutex.ReleaseMutex();
304                        }
305
306
307                        ValueKey valueKey = new ValueKey();
308                        int blocksize = 0;
309                        nextWildcard = -3;
310                        try
311                        {
312                            string key = "";
313                            if (useKeyblocks)
314                                key = pattern.getKeyBlock(ref blocksize, ref nextWildcard);
315                            if (key == null)
316                                useKeyblocks = false;
317                            if (!useKeyblocks)
318                                key = pattern.getKey();
319                            valueKey.key = key;
320                        }
321                        catch (Exception ex)
322                        {
323                            GuiLogMessage("Could not get next key: " + ex.Message, NotificationLevel.Error);
324                            return;
325                        }
326
327                        int[] arrayPointers = null;
328                        int[] arraySuccessors = null;
329                        int[] arrayUppers = null;
330                        byte[] keya = ControlMaster.getKeyFromString(valueKey.key, ref arrayPointers, ref arraySuccessors, ref arrayUppers);
331                        if (keya == null)
332                        {
333                            useKeyblocks = false;
334                            nextWildcard = -2;
335                            continue;   //try again
336                        }
337
338                        if (arrayPointers == null)  //decrypt only one key
339                        {
340                            if (!decryptAndCalculate(sender, bytesToUse, ref valueKey, keya, 0, null))
341                                return;
342                            doneKeysArray[threadid]++;
343                            keycounterArray[threadid]++;
344                            keysLeft[threadid]--;
345                        }
346                        else  //decrypt several keys
347                        {
348                            int counter = 0;
349                            if (!bruteforceBlock(sender, bytesToUse, ref valueKey, keya, arrayPointers, arraySuccessors, arrayUppers, 0, ref counter, pattern))
350                                return;
351                            doneKeysArray[threadid] += blocksize;
352                            keycounterArray[threadid] += blocksize;
353                            keysLeft[threadid] -= blocksize;
354                        }
355                    } while (pattern.nextKey(nextWildcard) && !stop);
356
357                    if (stop)
358                        return;
359
360                    //Let's wait until another thread is willing to share with us:
361                    pattern = null;
362                    ThreadStackElement el = new ThreadStackElement();
363                    el.ev = new AutoResetEvent(false);
364                    el.threadid = threadid;
365                    patterns[threadid] = null;
366                    threadStack.Push(el);
367                    GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
368                    el.ev.WaitOne();
369                    GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
370                    pattern = patterns[threadid];
371                }
372            }
373            finally
374            {
375                sender.Dispose();
376            }
377        }
378
379        #region bruteforce methods
380
381        private bool bruteforceBlock(IControlEncryption sender, int bytesToUse, ref ValueKey valueKey, byte[] keya, int[] arrayPointers,
382            int[] arraySuccessors, int[] arrayUppers, int arrayPointer, ref int counter, KeyPattern pattern)
383        {
384            byte store = keya[arrayPointers[arrayPointer]];
385            while (!stop)
386            {
387                if (arrayPointer + 1 < arrayPointers.Length && arrayPointers[arrayPointer + 1] != -1)
388                {
389                    if (!bruteforceBlock(sender, bytesToUse, ref valueKey, keya, arrayPointers, arraySuccessors, arrayUppers, arrayPointer + 1, ref counter, pattern))
390                        return false;
391                }
392                else
393                {
394                    if (!decryptAndCalculate(sender, bytesToUse, ref valueKey, keya, counter, pattern))
395                        return false;
396                }
397
398                if (keya[arrayPointers[arrayPointer]] + arraySuccessors[arrayPointer] <= arrayUppers[arrayPointer])
399                {
400                    keya[arrayPointers[arrayPointer]] += (byte)arraySuccessors[arrayPointer];
401                    counter++;
402                }
403                else
404                    break;
405            }
406            keya[arrayPointers[arrayPointer]] = store;
407            if (stop)
408                return false;
409            return true;
410        }
411
412        private bool decryptAndCalculate(IControlEncryption sender, int bytesToUse, ref ValueKey valueKey, byte[] keya, int counter, KeyPattern pattern)
413        {
414            try
415            {
416                byte[] decryptedData = GetByteFromCryptoolStream(this.DecryptedData);
417                valueKey.decryption = sender.Decrypt(decryptedData, keya);
418                //valueKey.decryption = sender.Decrypt(keya, bytesToUse);
419            }
420            catch (Exception ex)
421            {
422                GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
423                GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
424                return false;
425            }
426
427            try
428            {
429                valueKey.value = CostMaster.calculateCost(valueKey.decryption);
430            }
431            catch (Exception ex)
432            {
433                GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
434                return false;
435            }
436
437            if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
438            {
439                if (valueKey.value > value_threshold)
440                {
441                    if (pattern != null)
442                        valueKey.key = pattern.getKey(counter);
443                    valuequeue.Enqueue(valueKey);
444                }
445            }
446            else
447            {
448                if (valueKey.value < value_threshold)
449                {
450                    if (pattern != null)
451                        valueKey.key = pattern.getKey(counter);
452                    valuequeue.Enqueue(valueKey);
453                }
454            }
455            return true;
456        }
457
458        #endregion
459
460        #endregion
461
462        public void process(IControlEncryption sender)
463        {
464            if (sender == null || costMaster == null)
465                return;
466            if (!Pattern.testWildcardKey(settings.Key))
467            {
468                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
469                return;
470            }
471            Pattern.WildcardKey = settings.Key;
472            bruteforcePattern(Pattern, sender);
473        }
474
475        // modified by Christian Arnold 2009.12.07 - return type LinkedList (top10List)
476        // main entry point to the KeySearcher
477        private LinkedList<ValueKey> bruteforcePattern(KeyPattern pattern, IControlEncryption sender)
478        {
479            int maxInList = 10;
480            LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
481            fillListWithDummies(maxInList, costList);
482
483            stop = false;
484            if (!pattern.testWildcardKey(settings.Key))
485            {
486                GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
487                return null;
488            }
489
490            int bytesToUse = 0;
491
492            try
493            {
494                bytesToUse = CostMaster.getBytesToUse();
495            }
496            catch (Exception ex)
497            {
498                GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
499                return null;
500            }
501
502            BigInteger size = pattern.size();
503            KeyPattern[] patterns = splitPatternForThreads(pattern);
504
505            valuequeue = Queue.Synchronized(new Queue());
506
507            BigInteger[] doneKeysA = new BigInteger[patterns.Length];
508            BigInteger[] keycounters = new BigInteger[patterns.Length];
509            BigInteger[] keysleft = new BigInteger[patterns.Length];
510            Stack threadStack = Stack.Synchronized(new Stack());
511            startThreads(sender, bytesToUse, patterns, doneKeysA, keycounters, keysleft, threadStack);
512
513            //update message:
514            while (!stop)
515            {
516                Thread.Sleep(1000);
517
518                updateToplist(costList);
519
520                #region calculate global counters from local counters
521                BigInteger keycounter = 0;
522                BigInteger doneKeys = 0;
523                foreach (BigInteger dk in doneKeysA)
524                    doneKeys += dk;
525                foreach (BigInteger kc in keycounters)
526                    keycounter += kc;
527                #endregion
528
529                if (keycounter > size)
530                    GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
531
532                #region determination of the thread with most keys
533                if (size - keycounter > 1000)
534                {
535                    maxThreadMutex.WaitOne();
536                    BigInteger max = 0;
537                    int id = -1;
538                    for (int i = 0; i < patterns.Length; i++)
539                        if (keysleft[i] != null && keysleft[i] > max)
540                        {
541                            max = keysleft[i];
542                            id = i;
543                        }
544                    maxThread = id;
545                    maxThreadMutex.ReleaseMutex();
546                }
547                #endregion
548
549                showProgress(costList, size, keycounter, doneKeys);
550
551                #region set doneKeys to 0
552                doneKeys = 0;
553                for (int i = 0; i < doneKeysA.Length; i++)
554                    doneKeysA[i] = 0;
555                #endregion
556
557                if (keycounter >= size)
558                    break;
559            }//end while
560
561            //wake up all sleeping threads, so they can stop:
562            while (threadStack.Count != 0)
563                ((ThreadStackElement)threadStack.Pop()).ev.Set();
564
565            if (!stop)
566                ProgressChanged(1, 1);
567
568            return costList;
569        }
570
571        private void showProgress(LinkedList<ValueKey> costList, BigInteger size, BigInteger keycounter, BigInteger doneKeys)
572        {
573            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
574
575            LinkedListNode<ValueKey> linkedListNode;
576            ProgressChanged(Math.Pow(10, keycounter.log(10) - size.log(10)), 1.0);
577
578            if (QuickWatchPresentation.IsVisible && doneKeys != 0 && !stop)
579            {
580                double time = (Math.Pow(10, (size - keycounter).log(10) - doneKeys.log(10)));
581                TimeSpan timeleft = new TimeSpan(-1);
582
583                try
584                {
585                    if (time / (24 * 60 * 60) <= int.MaxValue)
586                    {
587                        int days = (int)(time / (24 * 60 * 60));
588                        time = time - (days * 24 * 60 * 60);
589                        int hours = (int)(time / (60 * 60));
590                        time = time - (hours * 60 * 60);
591                        int minutes = (int)(time / 60);
592                        time = time - (minutes * 60);
593                        int seconds = (int)time;
594
595                        timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
596                    }
597                }
598                catch
599                {
600                    //can not calculate time span
601                }
602
603                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
604                {
605                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Text = "" + doneKeys;
606                    if (timeleft != new TimeSpan(-1))
607                    {
608                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "" + timeleft;
609                        try
610                        {
611                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "" + DateTime.Now.Add(timeleft);
612                        }
613                        catch
614                        {
615                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
616                        }
617                    }
618                    else
619                    {
620                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "incalculable :-)";
621                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
622                    }
623
624                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Clear();
625                    linkedListNode = costList.First;
626                   
627                    int i = 0;
628                    while (linkedListNode != null)
629                    {
630                        i++;
631
632                        ResultEntry entry = new ResultEntry();
633                        entry.Ranking = "" + i;
634                        entry.Value = "" + Math.Round(linkedListNode.Value.value,3);
635                        entry.Key = linkedListNode.Value.key;
636                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
637
638                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Add(entry);
639                        linkedListNode = linkedListNode.Next;
640                    }
641                }
642                , null);
643            }//end if
644
645
646            if (!stop && QuickWatchPresentation.IsVisible)
647            {
648
649                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
650                {
651                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Clear();
652                    linkedListNode = costList.First;                   
653                    int i = 0;
654
655                    while (linkedListNode != null)
656                    {
657                        i++;
658
659                        ResultEntry entry = new ResultEntry();
660                        entry.Ranking = "" + i;
661                        entry.Value = "" + Math.Round(linkedListNode.Value.value, 3);
662                        entry.Key = linkedListNode.Value.key;
663                        entry.Text = enc.GetString(linkedListNode.Value.decryption);
664
665                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).entries.Add(entry);
666                        linkedListNode = linkedListNode.Next;
667                    }
668                }
669                , null);
670            }
671        }
672
673        #region For TopList
674
675        private void fillListWithDummies(int maxInList, LinkedList<ValueKey> costList)
676        {
677            ValueKey valueKey = new ValueKey();
678            if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
679                valueKey.value = double.MaxValue;
680            else
681                valueKey.value = double.MinValue;
682            valueKey.key = "dummykey";
683            valueKey.decryption = new byte[0];
684            value_threshold = valueKey.value;
685            LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
686            for (int i = 1; i < maxInList; i++)
687            {
688                node = costList.AddAfter(node, valueKey);
689            }
690        }
691
692        private void updateToplist(LinkedList<ValueKey> costList)
693        {
694            LinkedListNode<ValueKey> node;
695            while (valuequeue.Count != 0)
696            {
697                ValueKey vk = (ValueKey)valuequeue.Dequeue();
698                if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
699                {
700                    if (vk.value > costList.Last().value)
701                    {
702                        node = costList.First;
703                        while (node != null)
704                        {
705                            if (vk.value > node.Value.value)
706                            {
707                                costList.AddBefore(node, vk);
708                                costList.RemoveLast();
709                                value_threshold = costList.Last.Value.value;
710                                break;
711                            }
712                            node = node.Next;
713                        }//end while
714                    }//end if
715                }
716                else
717                {
718                    if (vk.value < costList.Last().value)
719                    {
720                        node = costList.First;
721                        while (node != null)
722                        {
723                            if (vk.value < node.Value.value)
724                            {
725                                costList.AddBefore(node, vk);
726                                costList.RemoveLast();
727                                value_threshold = costList.Last.Value.value;
728                                break;
729                            }
730                            node = node.Next;
731                        }//end while
732                    }//end if
733                }
734            }
735        }
736
737        #endregion
738
739        private void startThreads(IControlEncryption sender, int bytesToUse, KeyPattern[] patterns, BigInteger[] doneKeysA, BigInteger[] keycounters, BigInteger[] keysleft, Stack threadStack)
740        {
741            for (int i = 0; i < patterns.Length; i++)
742            {
743                WaitCallback worker = new WaitCallback(KeySearcherJob);
744                doneKeysA[i] = new BigInteger();
745                keycounters[i] = new BigInteger();
746                ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
747            }
748        }
749
750        private KeyPattern[] splitPatternForThreads(KeyPattern pattern)
751        {
752            KeyPattern[] patterns = new KeyPattern[settings.CoresUsed + 1];
753            if (settings.CoresUsed > 0)
754            {
755                KeyPattern[] patterns2 = pattern.split();
756                patterns[0] = patterns2[0];
757                patterns[1] = patterns2[1];
758                int p = 1;
759                int threads = settings.CoresUsed - 1;
760                while (threads > 0)
761                {
762                    int maxPattern = -1;
763                    BigInteger max = 0;
764                    for (int i = 0; i <= p; i++)
765                        if (patterns[i].size() > max)
766                        {
767                            max = patterns[i].size();
768                            maxPattern = i;
769                        }
770                    KeyPattern[] patterns3 = patterns[maxPattern].split();
771                    patterns[maxPattern] = patterns3[0];
772                    patterns[++p] = patterns3[1];
773                    threads--;
774                }
775            }
776            else
777                patterns[0] = Pattern;
778            return patterns;
779        }
780
781        private void keyPatternChanged()
782        {
783            Pattern = new KeyPattern(controlMaster.getKeyPattern());
784        }
785
786        // set to protected by Christian Arnold - 2009.12.06
787        protected virtual void onStatusChanged(IControl sender, bool readyForExecution)
788        {
789            // doesn't work anymore, because Encryption PlugIns were changed radical!!! Arnie 2010.01.12
790            if (readyForExecution)
791            {
792                this.process((IControlEncryption)sender);
793            }
794        }
795
796
797        // added by Arnie - 2009.12.07
798        public delegate void BruteforcingEnded(LinkedList<ValueKey> top10List);
799        /// <summary>
800        /// This event gets thrown after Bruteforcing had ended. This is no evidence, that bruteforcing was successful.
801        /// But when the returned List is filled, we have (at least a part) of the possible best keys
802        /// </summary>
803        public event BruteforcingEnded OnBruteforcingEnded;
804
805        // added by Arnie -2009.12.02
806        // for inheritance reasons
807        public void BruteforcePattern(KeyPattern pattern, IControlEncryption encryptControl, IControlCost costControl)
808        {
809            //ControlMaster = encryptControl;
810            //CostMaster = costControl;
811            LinkedList<ValueKey> lstRet = bruteforcePattern(pattern, encryptControl);
812            if(OnBruteforcingEnded != null)
813                OnBruteforcingEnded(lstRet);
814        }
815
816        #endregion
817
818        public void GuiLogMessage(string message, NotificationLevel loglevel)
819        {
820            if (OnGuiLogNotificationOccured != null)
821                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
822        }
823
824        public void ProgressChanged(double value, double max)
825        {
826            if (OnPluginProgressChanged != null)
827            {
828                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
829
830            }
831        }
832
833        /// <summary>
834        /// used for delivering the results from the worker threads to the main thread:
835        /// </summary>
836        public struct ValueKey
837        {
838            public double value;
839            public String key;
840            public byte[] decryption;
841        };
842    }
843
844    /// <summary>
845    /// Represents one entry in our result list
846    /// </summary>
847    public class ResultEntry
848    {
849        public string Ranking { get; set; }
850        public string Value { get; set; }
851        public string Key { get; set; }
852        public string Text { get; set; }
853
854    }
855}
Note: See TracBrowser for help on using the repository browser.