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

Last change on this file since 761 was 761, checked in by kopal, 12 years ago

renamed "blocksize" to "bytesToUse"

File size: 16.6 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 int initKeyIteration(string key)
139        {
140            int 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                int size = Pattern.initKeyIteration(settings.Key);
278                int bytesToUse = CostMaster.getBytesToUse();
279                string key;
280                int counter = 0;
281                int 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                    counter++;                   
332                    ProgressChanged(counter, 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                        GuiLogMessage("Working with " + doneKeys + " Keys/sec", NotificationLevel.Info);                       
341                       
342                        int seconds = (size - counter) / doneKeys;
343                        TimeSpan secondsleft = new TimeSpan(0, 0, 0, seconds, 0);
344
345                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
346                        {
347                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Text = "" + doneKeys;
348                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "" + secondsleft;
349                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "" + DateTime.Now.AddSeconds(seconds);
350
351                        }
352                        , null);
353                        doneKeys = 0;
354
355                        if (QuickWatchPresentation.IsVisible)
356                        {
357                            text = "Calculated value/key - list:\r\n";
358                            linkedListNode = costList.First;
359                            while (linkedListNode != null)
360                            {
361                                text += linkedListNode.Value.value + " = " + linkedListNode.Value.key + "\r\n";
362                                linkedListNode = linkedListNode.Next;
363                            }
364                           
365                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
366                            {
367                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).logging.Text = text;
368                            }
369                            , null);
370                        }
371                    }
372
373                } while (Pattern.nextKey() && !stop);
374
375                text = "Calculated value/key - list:\r\n";
376                linkedListNode = costList.First;
377                while (linkedListNode != null)
378                {
379                    text += linkedListNode.Value.value + " = " + linkedListNode.Value.key + "\r\n";
380                    linkedListNode = linkedListNode.Next;
381                }
382                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
383                {
384                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).logging.Text = text;
385                }
386                , null);
387               
388            }//end if
389        }
390
391        public void PostExecution()
392        {
393        }
394
395        public void Pause()
396        {
397        }
398
399        public void Stop()
400        {
401            stop = true;
402        }
403
404        public void Initialize()
405        {
406        }
407
408        public void Dispose()
409        {
410        }
411
412        #endregion
413
414        #region INotifyPropertyChanged Members
415
416        public event PropertyChangedEventHandler PropertyChanged;
417
418        public void OnPropertyChanged(string name)
419        {
420            if (PropertyChanged != null)
421            {
422                PropertyChanged(this, new PropertyChangedEventArgs(name));
423            }
424        }
425
426        #endregion
427
428        private void keyPatternChanged()
429        {
430            Pattern = new KeyPattern(controlMaster.getKeyPattern());
431        }
432
433        private void onStatusChanged(IControl sender, bool readyForExecution)
434        {
435            if (readyForExecution)
436            {
437                this.process((IControlEncryption)sender);
438            }
439        }
440
441        #region IControlEncryption Members
442
443        private IControlEncryption controlMaster;
444        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
445        public IControlEncryption ControlMaster
446        {
447            get { return controlMaster; }
448            set
449            {
450                if (controlMaster != null)
451                {
452                    controlMaster.keyPatternChanged -= keyPatternChanged;
453                    controlMaster.OnStatusChanged -= onStatusChanged;
454                }
455                if (value != null)
456                {
457                    Pattern = new KeyPattern(value.getKeyPattern());
458                    value.keyPatternChanged += keyPatternChanged;
459                    value.OnStatusChanged += onStatusChanged;
460                    controlMaster = value;
461                    OnPropertyChanged("ControlMaster");
462                   
463                }
464                else
465                    controlMaster = null;
466            }
467        }
468
469        #endregion
470
471        #region IControlCost Members
472
473        private IControlCost costMaster;
474        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
475        public IControlCost CostMaster
476        {
477            get { return costMaster; }
478            set
479            {
480                costMaster = value;
481            }
482        }
483
484        #endregion
485
486        public void GuiLogMessage(string message, NotificationLevel loglevel)
487        {
488            if (OnGuiLogNotificationOccured != null)
489                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
490        }
491
492        public void ProgressChanged(double value, double max)
493        {
494            if (OnPluginProgressChanged != null)
495            {
496                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
497
498            }
499        }
500
501        private struct ValueKey
502        {
503            public double value;
504            public String key;
505        };
506    }
507}
508
Note: See TracBrowser for help on using the repository browser.