source: trunk/CrypPlugins/BooleanFunctionParser/BooleanFunctionParser.cs @ 832

Last change on this file since 832 was 832, checked in by Sören Rinne, 12 years ago
  • slight changes in BerlekampMassey
  • changed CubeAttack, BooleanFunctionParser, Trivium to implement only one Controller interface (IControlGenerateBlackboxOutputBit)
  • modified samples
File size: 37.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6using Cryptool.PluginBase;
7using System.IO;
8using System.ComponentModel;
9using System.Windows.Controls;
10using Cryptool.PluginBase.Cryptography;
11using Cryptool.PluginBase.IO;
12using Cryptool.PluginBase.Miscellaneous;
13using System.Security.Cryptography;
14// for [MethodImpl(MethodImplOptions.Synchronized)]
15using System.Runtime.CompilerServices;
16// for RegEx
17using System.Text.RegularExpressions;
18// for IControl
19using Cryptool.PluginBase.Control;
20// reference to the CubeAttackController interface (own dll)
21using Cryptool.CubeAttackController;
22// for QuickwatchPresentaton
23using System.Windows.Threading;
24using System.Threading;
25
26namespace Cryptool.BooleanFunctionParser
27{
28    [Author("Soeren Rinne", "soeren.rinne@cryptool.de", "Ruhr-Universitaet Bochum, Chair for System Security", "http://www.trust.rub.de/")]
29    [PluginInfo(false, "Boolean Function Parser", "Boolean Function Parser (BFP). Computes the result of a boolean function f(i).", "BooleanFunctionParser/DetailedDescription/Description.xaml", "BooleanFunctionParser/Images/icon2.png")]
30    public class BooleanFunctionParser : IThroughput
31    {
32        #region Private variables
33
34        private BooleanFunctionParserPresentation booleanFunctionParserPresentation;
35        private BooleanFunctionParserSettings settings;
36        private string inputFunction;
37        //private bool[] inputVariableOne;
38        //private bool[] inputVariableTwo;
39        //private bool[] inputVariableThree;
40        private bool output;
41        private bool lastInputWasFunction = false;
42        private int inputs = 1;
43        private bool canSendPropertiesChangedEvent = true;
44
45        #endregion
46
47        #region Events
48        public event DynamicPropertiesChanged OnDynamicPropertiesChanged;
49        #endregion
50
51        #region Public variables
52
53        //public int inputOneFlag = 0;
54        //public int inputTwoFlag = 0;
55        //public int inputThreeFlag = 0;
56        public int[] additionalInputsFlag = null;
57
58        #endregion
59
60        #region Public interfaces
61
62        /// <summary>
63        /// Contructor
64        /// </summary>
65        public BooleanFunctionParser()
66        {
67            this.settings = new BooleanFunctionParserSettings();
68            settings.OnGuiLogNotificationOccured += settings_OnGuiLogNotificationOccured;
69            settings.PropertyChanged += settings_PropertyChanged;
70
71            booleanFunctionParserPresentation = new BooleanFunctionParserPresentation();
72            Presentation = booleanFunctionParserPresentation;
73            booleanFunctionParserPresentation.textBoxInputFunction.TextChanged += textBoxInput_TextChanged;
74            booleanFunctionParserPresentation.textBoxInputData.TextChanged += textBoxInput_TextChanged;
75
76            CanChangeDynamicProperty = true;
77            // Thomas says:
78            // No dynProp event in constructor - editor will read the property initial without the event.
79            // event can cause problems when using save files and is processed after
80            // connections have been restored.
81            CreateInputOutput(false);
82        }
83
84        void textBoxInput_TextChanged(object sender, TextChangedEventArgs e)
85        {
86            settings.HasChanges = true;
87        }
88
89        [PropertyInfo(Direction.InputData, "Boolean Function f(i)", "Boolean function f(i) to compute.", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
90        public String InputFunction
91        {
92            [MethodImpl(MethodImplOptions.Synchronized)]
93            get { return inputFunction; }
94            [MethodImpl(MethodImplOptions.Synchronized)]
95            set
96            {
97                inputFunction = value;
98                lastInputWasFunction = true;
99                OnPropertyChanged("InputFunction");
100            }
101        }
102
103        /*[PropertyInfo(Direction.InputData, "Function Variable One (i_1.j)", "Input a boolean value to be processed by the function", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
104        public bool[] InputOne
105        {
106            [MethodImpl(MethodImplOptions.Synchronized)]
107            get
108            {
109                return this.inputVariableOne;
110            }
111
112            [MethodImpl(MethodImplOptions.Synchronized)]
113            set
114            {
115                this.inputVariableOne = value;
116                lastInputWasFunction = false;
117                OnPropertyChanged("InputOne");
118                // clean inputOne
119                inputOneFlag = 1;
120            }
121        }
122
123        [PropertyInfo(Direction.InputData, "Function Variable Two (i_2.j)", "Input a boolean value to be processed by the function", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
124        public bool[] InputTwo
125        {
126            [MethodImpl(MethodImplOptions.Synchronized)]
127            get
128            {
129                return this.inputVariableTwo;
130            }
131
132            [MethodImpl(MethodImplOptions.Synchronized)]
133            set
134            {
135                this.inputVariableTwo = value;
136                lastInputWasFunction = false;
137                OnPropertyChanged("InputTwo");
138                // clean inputOne
139                inputTwoFlag = 1;
140            }
141        }
142
143        [PropertyInfo(Direction.InputData, "Function Variable Three (i_3.j)", "Input a boolean value to be processed by the function", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
144        public bool[] InputThree
145        {
146            [MethodImpl(MethodImplOptions.Synchronized)]
147            get
148            {
149                return this.inputVariableThree;
150            }
151
152            [MethodImpl(MethodImplOptions.Synchronized)]
153            set
154            {
155                this.inputVariableThree = value;
156                lastInputWasFunction = false;
157                OnPropertyChanged("InputThree");
158                // clean inputOne
159                inputThreeFlag = 1;
160            }
161        }*/
162
163        [PropertyInfo(Direction.OutputData, "Function output", "Output after procesing the given function.", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
164        public bool Output
165        {
166            [MethodImpl(MethodImplOptions.Synchronized)]
167            get
168            {
169                return output;
170            }
171            set
172            {   // is readonly
173            }
174        }
175
176        #endregion
177
178        #region IPlugin Members
179
180        public void Dispose()
181        {
182            settings.Function = (string)booleanFunctionParserPresentation.textBoxInputFunction.Dispatcher.Invoke(
183                DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
184                {
185                    return booleanFunctionParserPresentation.textBoxInputFunction.Text;
186                }, null);
187            settings.Data = (string)booleanFunctionParserPresentation.textBoxInputData.Dispatcher.Invoke(
188               DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
189               {
190                   return booleanFunctionParserPresentation.textBoxInputData.Text;
191               }, null);
192            settings.FunctionCube = (string)booleanFunctionParserPresentation.textBoxInputFunction2.Dispatcher.Invoke(
193                DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
194                {
195                    return booleanFunctionParserPresentation.textBoxInputFunction2.Text;
196                }, null);
197            settings.DataCube = (string)booleanFunctionParserPresentation.textBoxInputData2.Dispatcher.Invoke(
198               DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
199               {
200                   return booleanFunctionParserPresentation.textBoxInputData2.Text;
201               }, null);
202        }
203
204        public void Execute()
205        {
206            try
207            {
208                // do calculation only, if all input flags are clean (= 1) or last event was from the function and all inputs are dirty (= 0)
209                int sumOfFlags = 0;
210                //string allFlags = null;
211                foreach (int flag in additionalInputsFlag) {
212                    sumOfFlags += flag;
213                    //allFlags += flag.ToString();
214                }
215                //GuiLogMessage("sumOfFlags: " + sumOfFlags + ", addIFl: " + allFlags, NotificationLevel.Info);
216
217                //if (sumOfFlags == additionalInputsFlag.Length || (lastInputWasFunction == true && sumOfFlags == 0))
218                if (sumOfFlags == additionalInputsFlag.Length)
219                {
220                    // set all flags to zero
221                    for (int flagIteration = 0; flagIteration < additionalInputsFlag.Length; flagIteration++)
222                    {
223                        additionalInputsFlag[flagIteration] = 0;
224                    }
225                    // revert also state of inputFunction flag
226                    lastInputWasFunction = false;
227
228                    int intOutput = ParseBooleanFunction(null, null);
229                    if (intOutput == -1) return;
230                    else
231                    {
232                        output = Convert.ToBoolean(intOutput);
233                        OnPropertyChanged("Output");
234                    }
235                }
236            }
237            catch (Exception exception)
238            {
239                GuiLogMessage(exception.Message, NotificationLevel.Error);
240            }
241            finally
242            {
243                ProgressChanged(1, 1);
244            }
245        }
246
247        public void Initialize()
248        {
249            if (booleanFunctionParserPresentation.textBoxInputFunction != null)
250                booleanFunctionParserPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
251                {
252                    booleanFunctionParserPresentation.textBoxInputFunction.Text = settings.Function;
253                }, null);
254            if (booleanFunctionParserPresentation.textBoxInputData != null)
255                booleanFunctionParserPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
256                {
257                    booleanFunctionParserPresentation.textBoxInputData.Text = settings.Data;
258                }, null);
259            if (booleanFunctionParserPresentation.textBoxInputFunction2 != null)
260                booleanFunctionParserPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
261                {
262                    booleanFunctionParserPresentation.textBoxInputFunction2.Text = settings.FunctionCube;
263                }, null);
264            if (booleanFunctionParserPresentation.textBoxInputData2 != null)
265                booleanFunctionParserPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
266                {
267                    booleanFunctionParserPresentation.textBoxInputData2.Text = settings.DataCube;
268                }, null);
269            booleanFunctionParserPresentation.SwitchCubeView(settings.UseBFPforCube);
270        }
271
272        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
273        private void GuiLogMessage(string message, NotificationLevel logLevel)
274        {
275            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
276        }
277
278        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
279        private void ProgressChanged(double value, double max)
280        {
281            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
282        }
283
284        public event StatusChangedEventHandler OnPluginStatusChanged;
285
286        // catches PropertyChanged event from settings
287        void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
288        {
289            // if the count of inputs has been changed, renew all inputs
290            if (e.PropertyName == "CountOfInputs")
291            {
292                CreateInputOutput(true);
293            }
294            else if (e.PropertyName == "UseBFPforCube")
295            {
296                booleanFunctionParserPresentation.SwitchCubeView(settings.UseBFPforCube);
297            }
298        }
299
300        // catches LogNotification from settings
301        private void settings_OnGuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
302        {
303            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(args.Message, this, args.NotificationLevel));
304        }
305
306        public void Pause()
307        {
308           
309        }
310
311        public void PostExecution()
312        {
313           
314        }
315
316        public void PreExecution()
317        {
318           
319        }
320
321        public void CreateInputOutput(bool announcePropertyChange)
322        {
323            try
324            {
325                DicDynamicProperties.Clear();
326                inputs = 0;
327                additionalInputsFlag = new int[settings.CountOfInputs];
328                for (int i = 0; i < settings.CountOfInputs; i++)
329                {
330                    AddInput("Input " + i, "Boolean[] Input " + i);
331                    additionalInputsFlag[i] = 0;
332                }
333                // Event should be fired even if no additional inputs are set, because when
334                // setting back to zero editor needs the event to remove the input.
335                if (announcePropertyChange) DynamicPropertiesChanged();
336            }
337            catch (Exception exception)
338            {
339                GuiLogMessage(exception.Message, NotificationLevel.Error);
340            }
341        }
342
343        /* *******************************************************************************
344         * Main function to be used in the M/S mode and in general
345         * inputs:
346         * string function - the boolean function to be computed with variables
347         * bool[] inputVariables - a boolean array to replace the variables
348         *
349         * ouput:
350         * int - the one bit long result of the given function; returns -1 on any failure
351         * *******************************************************************************
352        */
353        public int ParseBooleanFunction(bool[] inputVariables, bool[] dataTwo)
354        {
355            string function = null;
356            // if function is empty, use input funtion (could happen in case of a master/slave call) or quickwatch function
357            // get quickwatch function
358            string quickwatchFunction = (string)this.booleanFunctionParserPresentation.textBoxInputFunction.Dispatcher.Invoke(DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
359            {
360                return booleanFunctionParserPresentation.textBoxInputFunction.Text;
361            }, booleanFunctionParserPresentation);
362            string quickwatchFunctionCube = (string)this.booleanFunctionParserPresentation.textBoxInputFunction2.Dispatcher.Invoke(DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
363            {
364                return booleanFunctionParserPresentation.textBoxInputFunction2.Text;
365            }, booleanFunctionParserPresentation);
366
367            if (inputFunction != null && inputFunction != string.Empty)
368                function = inputFunction;
369            else if (quickwatchFunction != null && quickwatchFunction != string.Empty)
370                function = quickwatchFunction;
371            else if (quickwatchFunctionCube != null && quickwatchFunctionCube != string.Empty && settings.UseBFPforCube == true)
372                function = quickwatchFunctionCube;
373            else
374                return -1;
375
376            // replace variables with data
377            string strExpression = ReplaceVariables(function, inputVariables, dataTwo);
378            // test if function is valid
379            string strExpressionTested = TestFunction(strExpression);
380            if (strExpressionTested == "foo")
381            {
382                GuiLogMessage(strExpression + " is not a binary expression (e.g. 1 + 0 * 1). Aborting now.", NotificationLevel.Error);
383                return -1;
384            }
385            else
386            {
387                //GuiLogMessage("Your expression with variables replaced: " + strExpression, NotificationLevel.Info);
388                output = EvaluateString(strExpressionTested);
389            }
390            // Just testing
391            //bool[] test = (bool[])getCurrentValue("Input 2");
392            //GuiLogMessage("InputTest: " + test[0].ToString(), NotificationLevel.Info);
393
394            return Convert.ToInt32(output);
395        }
396
397        #region private functions
398
399        private string makeStarsInText(Match m)
400        {
401            // Get the matched string.
402            string x = m.ToString();
403            // insert an * before the i
404            x = x.Insert(x.Length - 1, "*");
405            // a new star is born
406            return x;
407        }
408
409        private string ReplaceVariables(string strExpressionWithVariables, bool[] externDataOne, bool []externDataTwo)
410        {
411            // remove spaces
412            string strExpression = strExpressionWithVariables.Replace(" ", "");
413            // add * if there aren't any (and should be)
414            // example: x^2+x^2x^3 ==> x^2+x^2*x^3
415            Regex makeStars = new Regex("([0-9])i");
416            strExpression = makeStars.Replace(strExpression, new MatchEvaluator(makeStarsInText));
417
418            // replace variables with value and get numeric values from boolean inputs (if there are any)
419            /*if (inputOneFlag == 1 && inputVariableOne != null)
420            {
421                char[] strInputVariableOne = new char[inputVariableOne.Length];
422                for (int i = inputVariableOne.Length - 1; i >= 0; i--)
423                {
424                    // get numeric values from bool inputs
425                    strInputVariableOne[i] = inputVariableOne[i] ? '1' : '0';
426                    // replace variables with value
427                    string replacement = "i_1." + i;
428                    strExpression = strExpression.Replace(replacement, strInputVariableOne[i].ToString());
429                }
430            }
431            if (inputTwoFlag == 1 && inputVariableTwo != null)
432            {
433                char[] strInputVariableTwo = new char[inputVariableTwo.Length];
434                for (int i = inputVariableTwo.Length - 1; i >= 0; i--)
435                {
436                    // get numeric values from bool inputs
437                    strInputVariableTwo[i] = inputVariableTwo[i] ? '1' : '0';
438                    string replacement = "i_2." + i;
439                    strExpression = strExpression.Replace(replacement, strInputVariableTwo[i].ToString());
440                }
441            }
442            if (inputThreeFlag == 1 && inputVariableThree != null)
443            {
444                char[] strInputVariableThree = new char[inputVariableThree.Length];
445                for (int i = inputVariableThree.Length - 1; i >= 0; i--)
446                {
447                    // get numeric values from bool inputs
448                    strInputVariableThree[i] = inputVariableThree[i] ? '1' : '0';
449                    string replacement = "i_3." + i;
450                    strExpression = strExpression.Replace(replacement, strInputVariableThree[i].ToString());
451                }
452            }*/
453            // replace additional inputs data (if there are any)
454            for (int i = 0; i < inputs; i++)
455            {
456                if (getCurrentValue("Input " + i) != null)
457                {
458                    bool[] additionalTempValueBool = (bool[])methodGetValue("Input " + i);
459                    char[] strInputVariableAditionalTemp = new char[additionalTempValueBool.Length];
460                    for (int j = additionalTempValueBool.Length - 1; j >= 0; j--)
461                    {
462                        // get numeric values from bool inputs
463                        strInputVariableAditionalTemp[j] = additionalTempValueBool[j] ? '1' : '0';
464                        string replacement = "i_" + (i) + "." + j;
465                        strExpression = strExpression.Replace(replacement, strInputVariableAditionalTemp[j].ToString());
466                    }
467                }
468            }
469            // replace extern data (i_0.*) (if there is any)
470            if (externDataOne != null && externDataOne.Length != 0)
471            {
472                char[] strInputVariableExtern = new char[externDataOne.Length];
473                for (int i = strInputVariableExtern.Length - 1; i >= 0; i--)
474                {
475                    // get numeric values from bool inputs
476                    strInputVariableExtern[i] = externDataOne[i] ? '1' : '0';
477                    string replacement = "i_0." + i;
478                    strExpression = strExpression.Replace(replacement, strInputVariableExtern[i].ToString());
479                }
480            }
481            // replace quickwatch data (i_q.*) (if there is any)
482            if (settings.UseBFPforCube == false)
483            {
484                string quickwatchData = (string)this.booleanFunctionParserPresentation.textBoxInputData.Dispatcher.Invoke(DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
485                {
486                    return booleanFunctionParserPresentation.textBoxInputData.Text;
487                }, booleanFunctionParserPresentation);
488                if (quickwatchData != null && quickwatchData != string.Empty)
489                {
490                    char[] strInputVariableQuickwatch = new char[quickwatchData.Length];
491                    strInputVariableQuickwatch = quickwatchData.ToCharArray();
492                    for (int i = strInputVariableQuickwatch.Length - 1; i >= 0 ; i--)
493                    {
494                        string replacement = "i_q." + i;
495                        strExpression = strExpression.Replace(replacement, strInputVariableQuickwatch[i].ToString());
496                    }
497                }
498            } else if (settings.UseBFPforCube == true)
499            {
500                string quickwatchDataCube = (string)this.booleanFunctionParserPresentation.textBoxInputData2.Dispatcher.Invoke(DispatcherPriority.Normal, (DispatcherOperationCallback)delegate
501                {
502                    return booleanFunctionParserPresentation.textBoxInputData2.Text;
503                }, booleanFunctionParserPresentation);
504                // Cube Attack Online Phase
505                if (externDataTwo != null && externDataTwo.Length != 0)
506                {
507                    char[] strInputVariableExtern = new char[externDataOne.Length];
508                    for (int i = strInputVariableExtern.Length - 1; i >= 0; i--)
509                    {
510                        // get numeric values from bool inputs
511                        strInputVariableExtern[i] = externDataTwo[i] ? '1' : '0';
512                        string replacement = "i_q." + i;
513                        strExpression = strExpression.Replace(replacement, strInputVariableExtern[i].ToString());
514                    }
515                }
516                // Cube Attack Preprocessing Phase
517                else if (quickwatchDataCube != null && quickwatchDataCube != string.Empty)
518                {
519                    char[] strInputVariableQuickwatch = new char[quickwatchDataCube.Length];
520                    strInputVariableQuickwatch = quickwatchDataCube.ToCharArray();
521                    for (int i = strInputVariableQuickwatch.Length - 1; i >= 0; i--)
522                    {
523                        string replacement = "i_q." + i;
524                        strExpression = strExpression.Replace(replacement, strInputVariableQuickwatch[i].ToString());
525                    }
526                }
527               
528            }
529           
530
531            // replace AND, NAND, OR, NOR, XOR, NXOR with symbols
532            // NAND => -
533            //strExpression = strExpression.Replace("NAND", "-");
534            // AND => *
535            strExpression = strExpression.Replace("AND", "*");
536
537            // NOR => _
538            //strExpression = strExpression.Replace("NOR", "_");
539
540            // NXOR => °
541            //strExpression = strExpression.Replace("NXOR", "°");
542            // XOR => *
543            strExpression = strExpression.Replace("XOR", "+");
544
545            // OR => |
546            //strExpression = strExpression.Replace("OR", "|");
547
548            // replace ^ and & with symbols
549            // ^ => XOR => +
550            //strExpression = strExpression.Replace("^", "+");
551
552            // & => AND => *
553            //strExpression = strExpression.Replace("&", "*");
554
555            return strExpression;
556        }
557
558        // validates expression in function
559        private string TestFunction(string strExpression)
560        {
561            // remove spaces from given expression
562            string strExpressionNormalized = strExpression.Replace(" ", "");
563            char tab = '\u0009';
564            strExpressionNormalized = strExpressionNormalized.Replace(tab.ToString(), "");
565
566            // test if count of '(' equals count of ')'
567            Regex countLeftPRegEx = new Regex(@"\(");
568            Regex countRightPRegEx = new Regex(@"\)");
569            if (countLeftPRegEx.Matches(strExpressionNormalized).Count != countRightPRegEx.Matches(strExpressionNormalized).Count)
570            {
571                GuiLogMessage("The count of ( is not equal to the count of )", NotificationLevel.Error);
572                return "foo";
573            }
574
575            // test expression
576            Regex objBoolExpression = new Regex(@"([\(]?[\!]?)([0-1]([\\*]|[\\+]|[\\|]|[\\-]|[_]|[°]|[v]|[\\^]|[\\!])+[0-1]{1})");
577            if (!objBoolExpression.IsMatch(strExpressionNormalized))
578            {
579                GuiLogMessage("That's not a legal function", NotificationLevel.Error);
580                return "foo";
581            }
582            else
583            {
584                return strExpressionNormalized;
585            }
586        }
587
588        // solves string with variables replaced by values
589        private bool EvaluateString(string function)
590        {
591            string temp;
592
593            // test for parenthesis
594            int positionLeftParenthesis = function.IndexOf("(");
595            int positionRightParenthesis = function.LastIndexOf(")");
596
597            //GuiLogMessage("Position ( & ): " + positionLeftParenthesis + ", " + positionRightParenthesis, NotificationLevel.Debug);
598
599            if (positionLeftParenthesis != -1 && positionRightParenthesis != -1)
600            {
601                temp = function.Substring(positionLeftParenthesis + 1, positionRightParenthesis - positionLeftParenthesis - 1);
602                //GuiLogMessage("New function: " + temp, NotificationLevel.Debug);
603                bool parenthesisResult = EvaluateString(temp);
604                function = function.Remove(positionLeftParenthesis, positionRightParenthesis - positionLeftParenthesis + 1);
605                function = function.Insert(positionLeftParenthesis, Convert.ToInt32(parenthesisResult).ToString());
606            }
607
608            //GuiLogMessage("Function after '(':  " + function, NotificationLevel.Debug);
609
610            // test for exclamation mark aka 'NOT'
611            int positionExclamationMark = function.IndexOf("!");
612
613            while (positionExclamationMark != -1)
614            {
615                //GuiLogMessage("Position of '!': " + positionExclamationMark, NotificationLevel.Debug);
616
617                // remove exclamation mark
618                function = function.Remove(positionExclamationMark, 1);
619
620                // invert the binary digit following the excl. mark
621                string toInvert = function.Substring(positionExclamationMark, 1);
622                //GuiLogMessage("toInvert: " + toInvert, NotificationLevel.Debug);
623
624                if (toInvert == "1") toInvert = "0";
625                else toInvert = "1";
626                // remove old value
627                function = function.Remove(positionExclamationMark, 1);
628                // insert new value
629                function = function.Insert(positionExclamationMark, toInvert);
630
631                // any other NOTs in there?
632                positionExclamationMark = function.IndexOf("!");
633            }
634
635            //GuiLogMessage("Function after '!':  " + function, NotificationLevel.Debug);
636
637            // test for AND aka '*'
638            int positionAND = function.IndexOf("*");
639
640            while (positionAND != -1)
641            {
642                //GuiLogMessage("Position of '*': " + positionAND, NotificationLevel.Debug);
643
644                // get both operands
645                string operator1 = function.Substring(positionAND - 1, 1);
646                string operator2 = function.Substring(positionAND + 1, 1);
647                //GuiLogMessage("op1 and op2: " + operator1 + ", " + operator2, NotificationLevel.Info);
648
649                string sum = null;
650                try
651                {
652                    sum = (Int32.Parse(operator1) & Int32.Parse(operator2)).ToString();
653                }
654                catch (Exception ex)
655                {
656                    GuiLogMessage("sum fehlgeschlagen:", NotificationLevel.Info);
657                    GuiLogMessage("op1 and op2: " + operator1 + ", " + operator2, NotificationLevel.Info);
658                    GuiLogMessage("exception: " + ex, NotificationLevel.Info);
659                }
660               
661                //GuiLogMessage("sum: " + sum, NotificationLevel.Debug);
662
663                // remove old values
664                function = function.Remove(positionAND - 1, 3);
665
666                // insert new value
667                function = function.Insert(positionAND - 1, sum);
668                //GuiLogMessage("function: " + function, NotificationLevel.Debug);
669
670                // any other ANDs in there?
671                positionAND = function.IndexOf("*");
672            }
673
674            // test for XOR aka '+'
675            int positionXOR = function.IndexOf("+");
676
677            while (positionXOR != -1)
678            {
679                //GuiLogMessage("Position of '+': " + positionXOR, NotificationLevel.Debug);
680
681                // get both operands
682                string operator1 = function.Substring(positionXOR - 1, 1);
683                string operator2 = function.Substring(positionXOR + 1, 1);
684                //GuiLogMessage("op1 and op2: " + operator1 + ", " + operator2, NotificationLevel.Debug);
685
686                string product = (Int32.Parse(operator1) ^ Int32.Parse(operator2)).ToString();
687               
688                //GuiLogMessage("product: " + product, NotificationLevel.Debug);
689
690                // remove old values
691                function = function.Remove(positionXOR - 1, 3);
692
693                // insert new value
694                function = function.Insert(positionXOR - 1, product);
695                //GuiLogMessage("function: " + function, NotificationLevel.Debug);
696
697                // any other XORs in there?
698                positionXOR = function.IndexOf("+");
699            }
700
701            bool result = Convert.ToBoolean(Int32.Parse(function));
702
703            return result;
704        }
705
706        private object getCurrentValue(string name)
707        {
708            if (DicDynamicProperties.ContainsKey(name))
709            {
710                return DicDynamicProperties[name].Value;
711            }
712            return null;
713        }
714       
715        private void AddInput(string name, string toolTip)
716        {
717            inputs++;
718            if (name == null || name == string.Empty) name = "Input " + inputs;
719            DicDynamicProperties.Add(name,
720              new DynamicProperty(name, typeof(bool[]),
721                new PropertyInfoAttribute(Direction.InputData, name, toolTip, "", false, true, DisplayLevel.Beginner, QuickWatchFormat.None, null))
722            );
723        }
724
725        #endregion
726
727        [MethodImpl(MethodImplOptions.Synchronized)]
728        public object methodGetValue(string propertyKey)
729        {
730            // set flag of input <-- is now set in Execute()
731            //int numberInPropertyKey = Int32.Parse(propertyKey.Substring(propertyKey.Length - 1));
732            //additionalInputsFlag[numberInPropertyKey] = 0;
733
734            return getCurrentValue(propertyKey); // QuickWatchDataCall to Input values
735        }
736
737        [MethodImpl(MethodImplOptions.Synchronized)]
738        public void methodSetValue(string propertyKey, object value)
739        {
740            try
741            {
742                if (DicDynamicProperties.ContainsKey(propertyKey))
743                {
744                    DicDynamicProperties[propertyKey].Value = value;
745                    // set flag of input
746                    int numberInPropertyKey = Int32.Parse(propertyKey.Substring(6));
747                    additionalInputsFlag[numberInPropertyKey] = 1;
748                }
749
750                OnPropertyChanged(propertyKey);
751            }
752            catch (Exception ex)
753            {
754                GuiLogMessage(ex.Message, NotificationLevel.Error);
755            }
756        }
757
758        public System.Windows.Controls.UserControl QuickWatchPresentation
759        {
760            get { return Presentation; }
761        }
762
763        public UserControl Presentation { get; private set; }
764
765        public ISettings Settings
766        {
767            get
768            {
769                return (ISettings)this.settings;
770            }
771            set
772            {
773                this.settings = (BooleanFunctionParserSettings)value;
774            }
775        }
776
777        public void Stop()
778        {
779           
780        }
781
782        public Dictionary<string, DynamicProperty> dicDynamicProperties = new Dictionary<string, DynamicProperty>();
783
784        [DynamicPropertyInfo("methodGetValue", "methodSetValue", "CanChangeDynamicProperty", "OnDynamicPropertiesChanged", "CanSendPropertiesChangedEvent")]
785        public Dictionary<string, DynamicProperty> DicDynamicProperties
786        {
787            get { return dicDynamicProperties; }
788            set { dicDynamicProperties = value; }
789        }
790
791        public bool CanChangeDynamicProperty
792        {
793            get { return settings.CanChangeProperty; }
794            set { settings.CanChangeProperty = value; }
795        }
796
797        public bool CanSendPropertiesChangedEvent
798        {
799            get { return canSendPropertiesChangedEvent; }
800            set { canSendPropertiesChangedEvent = value; }
801        }
802
803        private void DynamicPropertiesChanged()
804        {
805            if (OnDynamicPropertiesChanged != null) OnDynamicPropertiesChanged(this);
806        }
807
808        #endregion
809
810        #region INotifyPropertyChanged Members
811
812        public event PropertyChangedEventHandler PropertyChanged;
813
814        public void OnPropertyChanged(string name)
815        {
816            if (PropertyChanged != null)
817            {
818                PropertyChanged(this, new PropertyChangedEventArgs(name));
819            }
820        }
821
822        #endregion
823
824        #region IControl
825
826        private IControlCubeAttack bfpSlave;
827        [PropertyInfo(Direction.ControlSlave, "BFP Slave", "Direct access to BFP.", "", DisplayLevel.Beginner)]
828        public IControlCubeAttack BFPSlave
829        {
830            get
831            {
832                if (bfpSlave == null)
833                    bfpSlave = new CubeAttackControl(this);
834                return bfpSlave;
835            }
836        }
837
838        #endregion
839    }
840
841    #region CubeAttackControl : IControlCubeAttack
842
843    public class CubeAttackControl : IControlCubeAttack
844    {
845        public event IControlStatusChangedEventHandler OnStatusChanged;
846        private BooleanFunctionParser plugin;
847
848        public CubeAttackControl(BooleanFunctionParser Plugin)
849        {
850            this.plugin = Plugin;
851        }
852
853        #region IControlEncryption Members
854
855        // here comes the slave side implementation of SolveFunction
856        public int GenerateBlackboxOutputBit(object dataOne, object dataTwo, object ignoreMe)
857        {
858            int resultInt;
859
860            bool[] myDataOneBool = null;
861            bool[] myDataTwoBool = null;
862
863            // parse objects and convert to boolean arrays
864            if (dataOne != null)
865            {
866                int[] myDataOneInt = dataOne as int[];
867                myDataOneBool = new bool[myDataOneInt.Length];
868                for (int i = 0; i < myDataOneInt.Length; i++)
869                {
870                    myDataOneBool[i] = Convert.ToBoolean(myDataOneInt[i]);
871                }
872            }
873
874            if (dataTwo != null)
875            {
876                int[] myDataTwoInt = dataTwo as int[];
877                myDataTwoBool = new bool[myDataTwoInt.Length];
878                for (int i = 0; i < myDataTwoInt.Length; i++)
879                {
880                    myDataTwoBool[i] = Convert.ToBoolean(myDataTwoInt[i]);
881                }
882            }
883
884            // the result is computed by calling the ParseBooleanFunction (step into it with F11)
885            // returns -1 on error (e.g. not a valid function)
886            resultInt = plugin.ParseBooleanFunction(myDataOneBool, myDataTwoBool);
887
888            return resultInt;
889        }
890
891        #endregion
892    }
893
894    #endregion
895}
Note: See TracBrowser for help on using the repository browser.