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

Last change on this file since 866 was 866, checked in by Sven Rech, 12 years ago

KeySearcher uses BigIntegers instead of longs now.

File size: 37.7 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;
14
15namespace KeySearcher
16{
17    public class KeyPattern
18    {
19        private class Wildcard
20        {
21            private char[] values = new char[256];
22            private int length;
23            private int counter;
24            public bool isSplit
25            {
26                get;
27                private set;
28            }
29           
30            public Wildcard(string valuePattern)
31            {
32                isSplit = false;
33                counter = 0;
34                length = 0;
35                int i = 1;
36                while (valuePattern[i] != ']')
37                {
38                    if (valuePattern[i + 1] == '-')
39                    {
40                        for (char c = valuePattern[i]; c <= valuePattern[i + 2]; c++)
41                            values[length++] = c;
42                        i += 2;
43                    }
44                    else
45                        values[length++] = valuePattern[i];
46                    i++;
47                }
48            }
49
50            public Wildcard(Wildcard wc)
51            {
52                isSplit = wc.isSplit;
53                length = wc.length;
54                counter = wc.counter;
55                for (int i = 0; i < 256; i++)
56                    values[i] = wc.values[i];
57            }
58
59            private Wildcard()
60            {
61            }
62
63            public Wildcard[] split()
64            {
65                int length = this.length - this.counter;
66                Wildcard[] wcs = new Wildcard[2];
67                wcs[0] = new Wildcard();
68                wcs[0].counter = 0;
69                wcs[0].length = length / 2;
70                wcs[1] = new Wildcard();
71                wcs[1].counter = 0;
72                wcs[1].length = length - wcs[0].length;
73                for (int i = 0; i < wcs[0].length; i++)
74                    wcs[0].values[i] = values[this.counter + i];
75                for (int i = 0; i < wcs[1].length; i++)
76                    wcs[1].values[i] = values[i + this.counter + wcs[0].length];
77                wcs[0].isSplit = true;
78                wcs[1].isSplit = true;
79                return wcs;
80            }
81
82            public char getChar()
83            {
84                return values[counter];
85            }
86
87            public char getChar(int add)
88            {
89                return values[(counter+add)%length];
90            }
91
92            public bool succ()
93            {
94                counter++;
95                if (counter >= length)
96                {
97                    counter = 0;
98                    return true;
99                }
100                return false;
101            }
102
103            public int size()
104            {
105                return length;
106            }
107
108
109            public int count()
110            {
111                return counter;
112            }
113
114            public void resetCounter()
115            {
116                counter = 0;
117            }
118        }
119
120        private string pattern;
121        private string key;       
122        private ArrayList wildcardList;
123
124        public KeyPattern(string pattern)
125        {
126            this.pattern = pattern;
127        }
128
129        public KeyPattern[] split()
130        {
131            KeyPattern[] patterns = new KeyPattern[2];
132            for (int i = 0; i < 2; i++)
133            {
134                patterns[i] = new KeyPattern(pattern);
135                patterns[i].key = key;
136                patterns[i].wildcardList = new ArrayList();
137            }
138            bool s = false;
139            for (int i = 0; i < wildcardList.Count; i++)
140            {
141                Wildcard wc = ((Wildcard)wildcardList[i]);
142                if (!s && (wc.size() - wc.count()) > 1)
143                {
144                    Wildcard[] wcs = wc.split();
145                    patterns[0].wildcardList.Add(wcs[0]);
146                    patterns[1].wildcardList.Add(wcs[1]);
147                    s = true;
148                }
149                else
150                {
151                    patterns[0].wildcardList.Add(new Wildcard(wc));
152                    Wildcard copy = new Wildcard(wc);
153                    if (s)
154                        copy.resetCounter();
155                    patterns[1].wildcardList.Add(copy);
156                }
157            }
158            if (!s)
159                throw new Exception("Can't be split!");
160            return patterns;
161        }
162
163        public string giveWildcardKey()
164        {
165            string res = "";
166            int i = 0;
167            while (i < pattern.Length)
168            {
169                if (pattern[i] != '[')
170                    res += pattern[i];
171                else
172                {
173                    res += '*';
174                    while (pattern[i] != ']')
175                        i++;
176                }
177                i++;
178            }
179            return res;
180        }
181
182        public bool testKey(string key)
183        {
184            int kcount = 0;
185            int pcount = 0;
186            while (kcount < key.Length && pcount < pattern.Length)
187            {
188                if (pattern[pcount] != '[')
189                {
190                    if (key[kcount] != '*' && pattern[pcount] != key[kcount])
191                        return false;
192                    kcount++;
193                    pcount++;
194                }
195                else
196                {
197                    bool contains = false;
198                    pcount++;
199                    while (pattern[pcount] != ']')
200                    {
201                        if (key[kcount] != '*')
202                        {
203                            if (pattern[pcount + 1] == '-')
204                            {
205                                if (key[kcount] >= pattern[pcount] && key[kcount] <= pattern[pcount + 2])
206                                    contains = true;
207                                pcount += 2;
208                            }
209                            else
210                                if (pattern[pcount] == key[kcount])
211                                    contains = true;
212                        }
213                        pcount++;
214                    }
215                    if (!contains && !(key[kcount] == '*'))
216                        return false;
217                    kcount++;
218                    pcount++;
219                }               
220            }
221            if (pcount != pattern.Length || kcount != key.Length)
222                return false;
223            return true;
224        }
225
226        public BigInteger initKeyIteration(string key)
227        {
228            BigInteger counter = 1;
229            this.key = key;
230            int pcount = 0;
231            wildcardList = new ArrayList();
232            for (int i = 0; i < key.Length; i++)
233            {
234                if (key[i] == '*')
235                {
236                    Wildcard wc = new Wildcard(pattern.Substring(pcount, pattern.IndexOf(']', pcount) + 1 - pcount));
237                    wildcardList.Add(wc);
238                    counter *= wc.size();
239                }
240
241                if (pattern[pcount] == '[')
242                    while (pattern[pcount] != ']')
243                        pcount++;
244                pcount++;
245            }
246            return counter;
247        }
248
249        public BigInteger size()
250        {
251            if (wildcardList == null)
252                return 0;
253            BigInteger counter = 1;
254            foreach (Wildcard wc in wildcardList)
255                    counter *= wc.size();
256            return counter;
257        }
258
259        /** used to jump to the next Key.         
260         * if nextWildcard == -1, we return false
261         * if nextWildcard == -2, we return true
262         * if nextWildcard == -3, we increase the rightmost wildcard
263         * if nextWildcard >= 0, we increase the wildcard on the position 'nextWildcard'
264         * returns false if there is no key left.
265         */
266        public bool nextKey(int nextWildcard)
267        {
268            if (nextWildcard == -2)
269                return true;
270            if (nextWildcard == -1)
271                return false;
272
273            int wildcardCount;
274            if (nextWildcard == -3)
275                wildcardCount = wildcardList.Count - 1;
276            else
277                wildcardCount = nextWildcard;
278            bool overflow = ((Wildcard)wildcardList[wildcardCount]).succ();
279            wildcardCount--;
280            while (overflow && (wildcardCount >= 0))
281                overflow = ((Wildcard)wildcardList[wildcardCount--]).succ();
282            return !overflow;
283        }
284
285        public string getKey()
286        {
287            string res = "";
288            int wildcardCount = 0;
289            for (int i = 0; i < key.Length; i++)
290            {
291                if (key[i] != '*')
292                    res += key[i];
293                else
294                {
295                    Wildcard wc = (Wildcard)wildcardList[wildcardCount++];
296                    res += wc.getChar();
297                }
298            }
299            return res;
300        }
301
302        public string getKey(int add)
303        {
304            string res = "";
305            int div = 1;
306            int wildcardCount = wildcardList.Count-1;
307            for (int i = key.Length-1; i >= 0; i--)
308            {
309                if (key[i] != '*')
310                    res += key[i];
311                else
312                {
313                    Wildcard wc = (Wildcard)wildcardList[wildcardCount--];
314                    if (add < div)
315                        res += wc.getChar();
316                    else
317                    {
318                        res += wc.getChar((add / div) % wc.size());
319                        div *= wc.size();
320                    }
321                }
322            }
323            char[] r = res.ToCharArray();
324            Array.Reverse(r);
325            return new string(r);
326        }
327
328        public string getKeyBlock(ref int blocksize, ref int nextWildcard)
329        {
330            const int MAXSIZE = 65536;
331            //find out how many wildcards we can group together:
332            blocksize = 1;
333            int pointer;
334            for (pointer = wildcardList.Count - 1; pointer >= 0; pointer--)
335            {
336                Wildcard wc = (Wildcard)wildcardList[pointer];
337                if (wc.isSplit || wc.count() != 0 || blocksize*wc.size() > MAXSIZE)               
338                    break;
339                else
340                    blocksize *= wc.size();
341            }           
342
343            if (pointer >= wildcardList.Count)
344                return null;
345
346            nextWildcard = pointer;           
347
348            //generate key:
349            string res = "";
350            int wildcardCount = 0;
351            for (int i = 0; i < key.Length; i++)
352            {
353                if (key[i] != '*')
354                    res += key[i];
355                else
356                {
357                    if (pointer < wildcardCount)
358                        res += "*";
359                    else
360                    {
361                        Wildcard wc = (Wildcard)wildcardList[wildcardCount++];
362                        res += wc.getChar();
363                    }
364                }
365            }
366            return res;
367        }
368
369    }
370   
371    [Author("Thomas Schmid", "thomas.schmid@cryptool.org", "Uni Siegen", "http://www.uni-siegen.de")]
372    //[Author("Sven Rech", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
373    [PluginInfo(true, "KeySearcher", "Bruteforces a decryption algorithm.", null, "KeySearcher/Images/icon.png")]
374    public class KeySearcher : IAnalysisMisc
375    {
376        private Queue valuequeue;
377        private double value_threshold;
378        private int maxThread;  //the thread with the most keys left
379        private Mutex maxThreadMutex = new Mutex();
380
381        private KeyPattern pattern = null;
382        public KeyPattern Pattern
383        {
384            get
385            {
386                return pattern;
387            }
388            set
389            {
390                pattern = value;
391                if ((settings.Key == null) ||((settings.Key != null) && !pattern.testKey(settings.Key)))
392                    settings.Key = pattern.giveWildcardKey();
393            }
394        }
395
396        private bool stop;
397
398        #region IPlugin Members
399
400        public event StatusChangedEventHandler OnPluginStatusChanged;
401
402        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
403
404        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
405
406        private KeySearcherSettings settings;
407
408        public KeySearcher()
409        {
410            settings = new KeySearcherSettings(this);
411            QuickWatchPresentation = new KeySearcherQuickWatchPresentation();
412        }
413
414        public ISettings Settings
415        {
416            get { return settings; }
417        }
418
419        public UserControl Presentation
420        {
421            get { return null; }
422        }
423
424        public UserControl QuickWatchPresentation
425        {
426            get;
427            private set;
428        }
429
430        public void PreExecution()
431        {
432        }
433
434        public void Execute()
435        {
436        }
437
438        private class ThreadStackElement
439        {
440            public AutoResetEvent ev;
441            public int threadid;
442        }
443
444        private void KeySearcherJob(object param)
445        {
446            object[] parameters = (object[])param;
447            KeyPattern[] patterns = (KeyPattern[])parameters[0];
448            int threadid = (int)parameters[1];
449            BigInteger[] doneKeysArray = (BigInteger[])parameters[2];
450            BigInteger[] keycounterArray = (BigInteger[])parameters[3];
451            BigInteger[] keysLeft = (BigInteger[])parameters[4];
452            IControlEncryption sender = (IControlEncryption)parameters[5];           
453            int bytesToUse = (int)parameters[6];
454            Stack threadStack = (Stack)parameters[7];
455
456            KeyPattern pattern = patterns[threadid];
457
458            bool useKeyblocks = true;
459
460            try
461            {
462                while (pattern != null)
463                {
464                    BigInteger size = pattern.size();
465                    keysLeft[threadid] = size;
466                    int nextWildcard;
467
468                    do
469                    {
470                        //if we are the thread with most keys left, we have to share them:
471                        if (maxThread == threadid && threadStack.Count != 0)
472                        {
473                            maxThreadMutex.WaitOne();
474                            if (maxThread == threadid && threadStack.Count != 0)
475                            {
476                                try
477                                {
478                                    KeyPattern[] split = pattern.split();
479                                    patterns[threadid] = split[0];
480                                    pattern = split[0];
481                                    ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
482                                    patterns[elem.threadid] = split[1];
483                                    elem.ev.Set();    //wake the other thread up                                   
484                                    size = pattern.size();
485                                    keysLeft[threadid] = size;
486                                }
487                                catch (Exception e)
488                                {
489                                    //pattern can't be split? who cares :)
490                                }
491                                maxThread = -1;
492                            }
493                            maxThreadMutex.ReleaseMutex();
494                        }
495
496
497                        ValueKey valueKey = new ValueKey();
498                        int blocksize = 0;
499                        nextWildcard = -3;
500                        try
501                        {
502                            string key = "";
503                            if (useKeyblocks)
504                                key = pattern.getKeyBlock(ref blocksize, ref nextWildcard);
505                            if (key == null)
506                                useKeyblocks = false;
507                            if (!useKeyblocks)
508                                key = pattern.getKey();
509                            valueKey.key = key;
510                        }
511                        catch (Exception ex)
512                        {
513                            GuiLogMessage("Could not get next key: " + ex.Message, NotificationLevel.Error);
514                            return;
515                        }
516
517                        int[] arrayPointers = null;
518                        int[] arraySuccessors = null;
519                        int[] arrayUppers = null;
520                        byte[] keya = ControlMaster.getKeyFromString(valueKey.key, ref arrayPointers, ref arraySuccessors, ref arrayUppers);
521                        if (keya == null)
522                        {
523                            useKeyblocks = false;
524                            nextWildcard = -2;
525                            continue;   //try again
526                        }
527
528                        if (arrayPointers == null)  //decrypt only one key
529                        {
530                            if (!decryptAndCalculate(sender, bytesToUse, ref valueKey, keya, 0, null))
531                                return;                           
532                            doneKeysArray[threadid]++;
533                            keycounterArray[threadid]++;
534                            keysLeft[threadid]--;
535                        }
536                        else  //decrypt several keys
537                        {
538                            int counter = 0;
539                            if (!bruteforceBlock(sender, bytesToUse, ref valueKey, keya, arrayPointers, arraySuccessors, arrayUppers, 0, ref counter, pattern))
540                                return;
541                            doneKeysArray[threadid] += blocksize;
542                            keycounterArray[threadid] += blocksize;
543                            keysLeft[threadid] -= blocksize;
544                        }
545                    } while (pattern.nextKey(nextWildcard) && !stop);
546
547                    if (stop)
548                        return;
549
550                    //Let's wait until another thread is willing to share with us:
551                    pattern = null;
552                    ThreadStackElement el = new ThreadStackElement();
553                    el.ev = new AutoResetEvent(false);
554                    el.threadid = threadid;
555                    patterns[threadid] = null;
556                    threadStack.Push(el);
557                    GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
558                    el.ev.WaitOne();
559                    GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
560                    pattern = patterns[threadid];
561                }
562            }
563            finally
564            {
565                sender.Dispose();
566            }
567        }
568       
569        private bool bruteforceBlock(IControlEncryption sender, int bytesToUse, ref ValueKey valueKey, byte[] keya, int[] arrayPointers, 
570            int[] arraySuccessors, int[] arrayUppers, int arrayPointer, ref int counter, KeyPattern pattern)
571        {
572            byte store = keya[arrayPointers[arrayPointer]];
573            while (!stop)
574            {
575                if (arrayPointer+1 < arrayPointers.Length && arrayPointers[arrayPointer+1] != -1)
576                {
577                    if (!bruteforceBlock(sender, bytesToUse, ref valueKey, keya, arrayPointers, arraySuccessors, arrayUppers, arrayPointer + 1, ref counter, pattern))
578                        return false;
579                }
580                else
581                {
582                    if (!decryptAndCalculate(sender, bytesToUse, ref valueKey, keya, counter, pattern))
583                        return false;
584                }
585
586                if (keya[arrayPointers[arrayPointer]] + arraySuccessors[arrayPointer] <= arrayUppers[arrayPointer])
587                {
588                    keya[arrayPointers[arrayPointer]] += (byte)arraySuccessors[arrayPointer];
589                    counter++;
590                }
591                else
592                    break;
593            }
594            keya[arrayPointers[arrayPointer]] = store;
595            if (stop)
596                return false;
597            return true;
598        }
599
600        private bool decryptAndCalculate(IControlEncryption sender, int bytesToUse, ref ValueKey valueKey, byte[] keya, int counter, KeyPattern pattern)
601        {
602            try
603            {
604                valueKey.decryption = sender.Decrypt(keya, bytesToUse);
605            }
606            catch (Exception ex)
607            {
608                GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
609                GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
610                return false;
611            }
612
613            try
614            {
615                valueKey.value = CostMaster.calculateCost(valueKey.decryption);
616            }
617            catch (Exception ex)
618            {
619                GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
620                return false;
621            }
622
623            if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
624            {
625                if (valueKey.value > value_threshold)
626                {
627                    if (pattern != null)
628                        valueKey.key = pattern.getKey(counter);
629                    valuequeue.Enqueue(valueKey);
630                }
631            }
632            else
633            {
634                if (valueKey.value < value_threshold)
635                {
636                    if (pattern != null)
637                        valueKey.key = pattern.getKey(counter);
638                    valuequeue.Enqueue(valueKey);
639                }
640            }
641            return true;
642        }
643
644        public void process(IControlEncryption sender)
645        {
646            if (sender != null && costMaster != null)
647            {
648                int maxInList = 10;
649                LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
650                ValueKey valueKey = new ValueKey();
651                if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
652                    valueKey.value = double.MaxValue;
653                else
654                    valueKey.value = double.MinValue;
655                valueKey.key = "dummykey";
656                valueKey.decryption = new byte[0];
657                value_threshold = valueKey.value;
658                LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
659                for (int i = 1; i < maxInList; i++)
660                {
661                    node = costList.AddAfter(node, valueKey);
662                }
663
664                stop = false;
665                if (!Pattern.testKey(settings.Key))
666                {
667                    GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
668                    return;
669                }
670
671                int bytesToUse = 0;
672
673                try
674                {
675                    bytesToUse = CostMaster.getBytesToUse();
676                }
677                catch (Exception ex)
678                {
679                    GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
680                    return;
681                }
682
683                LinkedListNode<ValueKey> linkedListNode;
684
685                KeyPattern[] patterns = new KeyPattern[settings.CoresUsed+1];
686                BigInteger size = Pattern.initKeyIteration(settings.Key);
687               
688                if (settings.CoresUsed > 0)
689                {
690                    KeyPattern[] patterns2 = Pattern.split();                   
691                    patterns[0] = patterns2[0];
692                    patterns[1] = patterns2[1];
693                    int p = 1;
694                    int threads = settings.CoresUsed - 1;
695                    while (threads > 0)
696                    {
697                        int maxPattern = -1;
698                        BigInteger max = 0;
699                        for (int i = 0; i <= p; i++)
700                            if (patterns[i].size() > max)
701                            {
702                                max = patterns[i].size();
703                                maxPattern = i;
704                            }
705                        KeyPattern[] patterns3 = patterns[maxPattern].split();
706                        patterns[maxPattern] = patterns3[0];
707                        patterns[++p] = patterns3[1];
708                        threads--;
709                    }
710                }
711                else
712                    patterns[0] = Pattern;
713
714                valuequeue = Queue.Synchronized(new Queue());
715
716                BigInteger[] doneKeysA = new BigInteger[patterns.Length];
717                BigInteger[] keycounters = new BigInteger[patterns.Length];
718                BigInteger[] keysleft = new BigInteger[patterns.Length];
719                Stack threadStack = Stack.Synchronized(new Stack());
720                for (int i = 0; i < patterns.Length; i++)
721                {
722                    WaitCallback worker = new WaitCallback(KeySearcherJob);
723                    doneKeysA[i] = new BigInteger();
724                    keycounters[i] = new BigInteger();
725                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
726                }
727               
728                //update message:
729                while (!stop)
730                {
731                    Thread.Sleep(1000);
732
733                    //update toplist:
734                    while (valuequeue.Count != 0)
735                    {
736                        ValueKey vk = (ValueKey)valuequeue.Dequeue();
737                        if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
738                        {
739                            if (vk.value > costList.Last().value)
740                            {
741                                node = costList.First;
742                                while (node != null)
743                                {
744                                    if (vk.value > node.Value.value)
745                                    {
746                                        costList.AddBefore(node, vk);
747                                        costList.RemoveLast();
748                                        value_threshold = costList.Last.Value.value;
749                                        break;
750                                    }
751                                    node = node.Next;
752                                }//end while
753                            }//end if
754                        }
755                        else
756                        {
757                            node = costList.First;
758                            if (vk.value < costList.Last().value)
759                            {
760                                while (node != null)
761                                {
762                                    if (vk.value < node.Value.value)
763                                    {
764                                        costList.AddBefore(node, vk);
765                                        costList.RemoveLast();
766                                        value_threshold = costList.Last.Value.value;
767                                        break;
768                                    }
769                                    node = node.Next;
770                                }//end while
771                            }//end if
772                        }
773                    }
774
775                    BigInteger keycounter = 0;
776                    BigInteger doneKeys = 0;
777                    foreach (BigInteger dk in doneKeysA)
778                        doneKeys += dk;
779                    foreach (BigInteger kc in keycounters)
780                        keycounter += kc;
781
782                    if (keycounter > size)
783                        GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
784
785                    //Let's determine which thread has the most keys to share:
786                    if (size - keycounter > 1000)
787                    {
788                        maxThreadMutex.WaitOne();
789                        BigInteger max = 0;
790                        int id = -1;
791                        for (int i = 0; i < patterns.Length; i++)
792                            if (keysleft[i] > max)
793                            {
794                                max = keysleft[i];
795                                id = i;
796                            }
797                        maxThread = id;
798                        maxThreadMutex.ReleaseMutex();
799                    }
800                                       
801                    ProgressChanged(Math.Pow(10, keycounter.log(10) - size.log(10)), 1.0);
802
803                    if (QuickWatchPresentation.IsVisible && doneKeys != 0 && !stop)
804                    {
805                        double time = (Math.Pow(10, (size - keycounter).log(10) - doneKeys.log(10)));
806                        TimeSpan timeleft = new TimeSpan(-1);
807
808                        try
809                        {
810                            if (time / (24 * 60 * 60) <= int.MaxValue)
811                            {
812                                int days = (int)(time / (24 * 60 * 60));
813                                time = time - (days * 24 * 60 * 60);
814                                int hours = (int)(time / (60 * 60));
815                                time = time - (hours * 60 * 60);
816                                int minutes = (int)(time / 60);
817                                time = time - (minutes * 60);
818                                int seconds = (int)time;
819
820                                timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
821                            }
822                        }
823                        catch
824                        {
825                            //can not calculate time span
826                        }
827
828                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
829                        {
830                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Text = "" + doneKeys;
831                            if (timeleft != new TimeSpan(-1))
832                            {
833                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "" + timeleft;
834                                try
835                                {
836                                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "" + DateTime.Now.Add(timeleft);
837                                }
838                                catch
839                                {
840                                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
841                                }
842                            }
843                            else
844                            {
845                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "incalculable :-)";
846                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
847                            }
848
849                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Clear();
850                            linkedListNode = costList.First;
851                            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
852                            int i = 0;
853                            while (linkedListNode != null)
854                            {
855                                i++;
856                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Add(i + ") " + Math.Round(linkedListNode.Value.value, 4) + " = " + linkedListNode.Value.key + " : \"" +
857                                    enc.GetString(linkedListNode.Value.decryption).Replace("\n", "").Replace("\r", "").Replace("\t", "") + "\"");
858                                linkedListNode = linkedListNode.Next;
859                            }
860                        }
861                        , null);
862                    }//end if
863                    doneKeys = 0;
864                    for (int i = 0; i < doneKeysA.Length; i++)
865                        doneKeysA[i] = 0;
866
867                    if (!stop && QuickWatchPresentation.IsVisible)
868                    {
869
870                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
871                        {
872                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Clear();
873                            linkedListNode = costList.First;
874                            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
875                            int i = 0;
876                            while (linkedListNode != null)
877                            {
878                                i++;
879                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Add(i + ") " + Math.Round(linkedListNode.Value.value, 4) + " = " + linkedListNode.Value.key + " : \"" +
880                                    enc.GetString(linkedListNode.Value.decryption).Replace("\n", "").Replace("\r", "").Replace("\t", "") + "\"");
881                                linkedListNode = linkedListNode.Next;
882                            }
883                        }
884                        , null);
885                    }
886
887                    if (keycounter >= size)
888                        break;
889                }//end while
890
891                //wake up all sleeping threads:
892                while (threadStack.Count != 0)
893                    ((ThreadStackElement)threadStack.Pop()).ev.Set();
894            }//end if
895
896            if (!stop)
897                ProgressChanged(1, 1);
898        }
899
900        public void PostExecution()
901        {
902        }
903
904        public void Pause()
905        {
906        }
907
908        public void Stop()
909        {
910            stop = true;
911        }
912
913        public void Initialize()
914        {
915        }
916
917        public void Dispose()
918        {
919        }
920
921        #endregion
922
923        #region INotifyPropertyChanged Members
924
925        public event PropertyChangedEventHandler PropertyChanged;
926
927        public void OnPropertyChanged(string name)
928        {
929            if (PropertyChanged != null)
930            {
931                PropertyChanged(this, new PropertyChangedEventArgs(name));
932            }
933        }
934
935        #endregion
936
937        private void keyPatternChanged()
938        {
939            Pattern = new KeyPattern(controlMaster.getKeyPattern());
940        }
941
942        private void onStatusChanged(IControl sender, bool readyForExecution)
943        {
944            if (readyForExecution)
945            {
946                this.process((IControlEncryption)sender);
947            }
948        }
949
950        #region IControlEncryption Members
951
952        private IControlEncryption controlMaster;
953        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
954        public IControlEncryption ControlMaster
955        {
956            get { return controlMaster; }
957            set
958            {
959                if (controlMaster != null)
960                {
961                    controlMaster.keyPatternChanged -= keyPatternChanged;
962                    controlMaster.OnStatusChanged -= onStatusChanged;
963                }
964                if (value != null)
965                {
966                    Pattern = new KeyPattern(value.getKeyPattern());
967                    value.keyPatternChanged += keyPatternChanged;
968                    value.OnStatusChanged += onStatusChanged;
969                    controlMaster = value;
970                    OnPropertyChanged("ControlMaster");
971                   
972                }
973                else
974                    controlMaster = null;
975            }
976        }
977
978        #endregion
979
980        #region IControlCost Members
981
982        private IControlCost costMaster;
983        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
984        public IControlCost CostMaster
985        {
986            get { return costMaster; }
987            set
988            {
989                costMaster = value;
990            }
991        }
992
993        #endregion
994
995        public void GuiLogMessage(string message, NotificationLevel loglevel)
996        {
997            if (OnGuiLogNotificationOccured != null)
998                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
999        }
1000
1001        public void ProgressChanged(double value, double max)
1002        {
1003            if (OnPluginProgressChanged != null)
1004            {
1005                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1006
1007            }
1008        }
1009
1010        private struct ValueKey
1011        {
1012            public double value;
1013            public String key;
1014            public byte[] decryption;
1015        };
1016    }
1017}
Note: See TracBrowser for help on using the repository browser.