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

Last change on this file since 780 was 780, checked in by kopal, 12 years ago
  • DES, removed bug if inputStream/outputStream null references after an execution
  • KeySearcher now calculates timespans even with very big integer values correctly
File size: 17.5 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;
13
14namespace KeySearcher
15{
16    public class KeyPattern
17    {
18        private class Wildcard
19        {
20            private char[] values = new char[256];
21            private int length;
22            private int counter;
23           
24            public Wildcard(string valuePattern)
25            {               
26                counter = 0;
27                length = 0;
28                int i = 1;
29                while (valuePattern[i] != ']')
30                {
31                    if (valuePattern[i + 1] == '-')
32                    {
33                        for (char c = valuePattern[i]; c <= valuePattern[i + 2]; c++)
34                            values[length++] = c;
35                        i += 2;
36                    }
37                    else
38                        values[length++] = valuePattern[i];
39                    i++;
40                }
41            }
42
43            public char getChar()
44            {               
45                return (char)values[counter];
46            }
47
48            public bool succ()
49            {
50                counter++;
51                if (counter >= length)
52                {
53                    counter = 0;
54                    return true;
55                }
56                return false;
57            }
58
59            public int Size()
60            {
61                return length;
62            }
63
64        }
65
66        private string pattern;
67        private string key;       
68        private ArrayList wildcardList;
69
70        public KeyPattern(string pattern)
71        {
72            this.pattern = pattern;
73        }
74
75        public string giveWildcardKey()
76        {
77            string res = "";
78            int i = 0;
79            while (i < pattern.Length)
80            {
81                if (pattern[i] != '[')
82                    res += pattern[i];
83                else
84                {
85                    res += '*';
86                    while (pattern[i] != ']')
87                        i++;
88                }
89                i++;
90            }
91            return res;
92        }
93
94        public bool testKey(string key)
95        {
96            int kcount = 0;
97            int pcount = 0;
98            while (kcount < key.Length && pcount < pattern.Length)
99            {
100                if (pattern[pcount] != '[')
101                {
102                    if (key[kcount] != '*' && pattern[pcount] != key[kcount])
103                        return false;
104                    kcount++;
105                    pcount++;
106                }
107                else
108                {
109                    bool contains = false;
110                    pcount++;
111                    while (pattern[pcount] != ']')
112                    {
113                        if (key[kcount] != '*')
114                        {
115                            if (pattern[pcount + 1] == '-')
116                            {
117                                if (key[kcount] >= pattern[pcount] && key[kcount] <= pattern[pcount + 2])
118                                    contains = true;
119                                pcount += 2;
120                            }
121                            else
122                                if (pattern[pcount] == key[kcount])
123                                    contains = true;
124                        }
125                        pcount++;
126                    }
127                    if (!contains && !(key[kcount] == '*'))
128                        return false;
129                    kcount++;
130                    pcount++;
131                }               
132            }
133            if (pcount != pattern.Length || kcount != key.Length)
134                return false;
135            return true;
136        }
137
138        public double initKeyIteration(string key)
139        {
140            double counter = 1;
141            this.key = key;
142            int pcount = 0;
143            wildcardList = new ArrayList();
144            for (int i = 0; i < key.Length; i++)
145            {
146                if (key[i] == '*')
147                {
148                    Wildcard wc = new Wildcard(pattern.Substring(pcount, pattern.IndexOf(']', pcount) + 1 - pcount));
149                    wildcardList.Add(wc);
150                    counter *= wc.Size();
151                }
152
153                if (pattern[pcount] == '[')
154                    while (pattern[pcount] != ']')
155                        pcount++;
156                pcount++;
157            }
158            return counter;
159        }
160
161        public bool nextKey()
162        {
163            int wildcardCount = wildcardList.Count-1;
164            bool overflow = ((Wildcard)wildcardList[wildcardCount]).succ();
165            wildcardCount--;
166            while (overflow && (wildcardCount >= 0))
167                overflow = ((Wildcard)wildcardList[wildcardCount--]).succ();
168            return !overflow;
169        }
170
171        public string getKey()
172        {
173            string res = "";
174            int wildcardCount = 0;
175            for (int i = 0; i < key.Length; i++)
176            {
177                if (key[i] != '*')
178                    res += key[i];
179                else
180                {
181                    Wildcard wc = (Wildcard)wildcardList[wildcardCount++];
182                    res += wc.getChar();
183                }
184            }
185            return res;
186        }
187    }
188   
189    [Author("Thomas Schmid", "thomas.schmid@cryptool.org", "Uni Siegen", "http://www.uni-siegen.de")]
190    //[Author("Sven Rech", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
191    [PluginInfo(true, "KeySearcher", "Bruteforces a decryption algorithm.", null, "KeySearcher/Images/icon.png")]
192    public class KeySearcher : IAnalysisMisc
193    {
194        private KeyPattern pattern = null;
195        public KeyPattern Pattern
196        {
197            get
198            {
199                return pattern;
200            }
201            set
202            {
203                pattern = value;
204                if ((settings.Key == null) ||((settings.Key != null) && !pattern.testKey(settings.Key)))
205                    settings.Key = pattern.giveWildcardKey();
206            }
207        }
208
209        private bool stop;
210
211        #region IPlugin Members
212
213        public event StatusChangedEventHandler OnPluginStatusChanged;
214
215        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
216
217        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
218
219        private KeySearcherSettings settings;       
220
221        public KeySearcher()
222        {
223            settings = new KeySearcherSettings(this);
224            QuickWatchPresentation = new KeySearcherQuickWatchPresentation();
225        }
226
227        public ISettings Settings
228        {
229            get { return settings; }
230        }
231
232        public UserControl Presentation
233        {
234            get { return null; }
235        }
236
237        public UserControl QuickWatchPresentation
238        {
239            get;
240            private set;
241        }
242
243        public void PreExecution()
244        {
245        }
246
247        public void Execute()
248        {
249        }
250
251        public void process(IControlEncryption sender)
252        {           
253
254            if (sender != null && costMaster != null)
255            {
256                int maxInList = 10;
257                LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
258                ValueKey valueKey = new ValueKey();               
259                if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
260                    valueKey.value = double.MaxValue;
261                else
262                    valueKey.value = double.MinValue;
263                valueKey.key = "dummykey";
264                LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
265                for (int i = 1; i < maxInList; i++)
266                {
267                    node = costList.AddAfter(node, valueKey);
268                }
269
270                stop = false;
271                if (!Pattern.testKey(settings.Key))
272                {
273                    GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
274                    return;
275                }
276
277                double size = Pattern.initKeyIteration(settings.Key);
278                int bytesToUse = CostMaster.getBytesToUse();
279                string key;
280                double keycounter = 0;
281                double doneKeys = 0;
282                string text = "";
283                LinkedListNode<ValueKey> linkedListNode;
284
285                DateTime lastTime = DateTime.Now;               
286                do
287                {                   
288                    key = Pattern.getKey();                   
289                    byte[] decryption = sender.Decrypt(ControlMaster.getKeyFromString(key), bytesToUse);
290
291                    valueKey = new ValueKey();
292                    valueKey.value = CostMaster.calculateCost(decryption);
293                    valueKey.key = key;
294                   
295                    if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
296                    {
297
298                       node = costList.First;
299
300                        while (node != null)
301                        {
302
303                            if (valueKey.value > node.Value.value)
304                            {
305                                costList.AddBefore(node, valueKey);
306                                break;
307                            }
308                            node = node.Next;
309                        }
310                    }
311                    else
312                    {
313                        node = costList.First;
314
315                        while (node != null)
316                        {
317
318                            if (valueKey.value < node.Value.value)
319                            {
320                                costList.AddBefore(node, valueKey);
321                                break;
322                            }
323                            node = node.Next;
324                        }
325                    }
326                    if (costList.Count > maxInList)
327                    {
328                        costList.RemoveLast();
329                    }
330
331                    keycounter++;                   
332                    ProgressChanged(keycounter, size);
333
334                    //Key per second calculation
335                    doneKeys++;
336                    TimeSpan duration = DateTime.Now - lastTime;
337                    if (duration.Seconds >= 1)
338                    {
339                        lastTime = DateTime.Now;
340                        double time = ((size - keycounter) / doneKeys);                       
341                        TimeSpan timeleft = new TimeSpan(-1) ;
342
343                        try
344                        {
345                            if (time / (24 * 60 * 60) <= int.MaxValue)
346                            {
347                                int days = (int)(time / (24 * 60 * 60));
348                                time = time - (days * 24 * 60 * 60);
349                                int hours = (int)(time / (60 * 60));
350                                time = time - (hours * 60 * 60);
351                                int minutes = (int)(time / 60);
352                                time = time - (minutes * 60);
353                                int seconds = (int)time;
354
355                                timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
356                            }                           
357                        }
358                        catch
359                        {
360                            //can not calculate time span
361                        }
362                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
363                        {
364                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Text = "" + doneKeys;
365                            if (timeleft != new TimeSpan(-1))
366                            {
367                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "" + timeleft;
368                                try
369                                {
370                                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "" + DateTime.Now.Add(timeleft);
371                                }catch{
372                                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a time far, far away...";
373                                }
374                            }
375                            else
376                            {
377                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "incalculable :-)";
378                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a time far, far away...";
379                            }
380                           
381
382                        }
383                        , null);
384                        doneKeys = 0;
385
386                        if (QuickWatchPresentation.IsVisible)
387                        {
388                            text = "Calculated value/key - list:\r\n";
389                            linkedListNode = costList.First;
390                            while (linkedListNode != null)
391                            {
392                                text += linkedListNode.Value.value + " = " + linkedListNode.Value.key + "\r\n";
393                                linkedListNode = linkedListNode.Next;
394                            }
395                           
396                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
397                            {
398                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).logging.Text = text;
399                            }
400                            , null);
401                        }
402                    }
403
404                } while (Pattern.nextKey() && !stop);               
405               
406            }//end if
407        }
408
409        public void PostExecution()
410        {
411        }
412
413        public void Pause()
414        {
415        }
416
417        public void Stop()
418        {
419            stop = true;
420        }
421
422        public void Initialize()
423        {
424        }
425
426        public void Dispose()
427        {
428        }
429
430        #endregion
431
432        #region INotifyPropertyChanged Members
433
434        public event PropertyChangedEventHandler PropertyChanged;
435
436        public void OnPropertyChanged(string name)
437        {
438            if (PropertyChanged != null)
439            {
440                PropertyChanged(this, new PropertyChangedEventArgs(name));
441            }
442        }
443
444        #endregion
445
446        private void keyPatternChanged()
447        {
448            Pattern = new KeyPattern(controlMaster.getKeyPattern());
449        }
450
451        private void onStatusChanged(IControl sender, bool readyForExecution)
452        {
453            if (readyForExecution)
454            {
455                this.process((IControlEncryption)sender);
456            }
457        }
458
459        #region IControlEncryption Members
460
461        private IControlEncryption controlMaster;
462        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
463        public IControlEncryption ControlMaster
464        {
465            get { return controlMaster; }
466            set
467            {
468                if (controlMaster != null)
469                {
470                    controlMaster.keyPatternChanged -= keyPatternChanged;
471                    controlMaster.OnStatusChanged -= onStatusChanged;
472                }
473                if (value != null)
474                {
475                    Pattern = new KeyPattern(value.getKeyPattern());
476                    value.keyPatternChanged += keyPatternChanged;
477                    value.OnStatusChanged += onStatusChanged;
478                    controlMaster = value;
479                    OnPropertyChanged("ControlMaster");
480                   
481                }
482                else
483                    controlMaster = null;
484            }
485        }
486
487        #endregion
488
489        #region IControlCost Members
490
491        private IControlCost costMaster;
492        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
493        public IControlCost CostMaster
494        {
495            get { return costMaster; }
496            set
497            {
498                costMaster = value;
499            }
500        }
501
502        #endregion
503
504        public void GuiLogMessage(string message, NotificationLevel loglevel)
505        {
506            if (OnGuiLogNotificationOccured != null)
507                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
508        }
509
510        public void ProgressChanged(double value, double max)
511        {
512            if (OnPluginProgressChanged != null)
513            {
514                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
515
516            }
517        }
518
519        private struct ValueKey
520        {
521            public double value;
522            public String key;
523        };
524    }
525}
526
Note: See TracBrowser for help on using the repository browser.