source: trunk/CrypPlugins/LFSR/LFSR.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: 35.7 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 Cryptool.PluginBase.Cryptography;
10using Cryptool.PluginBase.IO;
11using System.Windows.Controls;
12using Cryptool.PluginBase.Miscellaneous;
13using System.Security.Cryptography;
14// for [MethodImpl(MethodImplOptions.Synchronized)]
15using System.Runtime.CompilerServices;
16using System.Runtime.Remoting.Contexts;
17// for QuickwatchPresentation
18using System.Windows.Threading;
19using System.Threading;
20using System.Windows.Automation.Peers;
21// for RegEx
22using System.Text.RegularExpressions;
23
24namespace Cryptool.LFSR
25{
26    [Author("Soeren Rinne", "soeren.rinne@cryptool.de", "Ruhr-Universitaet Bochum, Chair for System Security", "http://www.trust.rub.de/")]
27    [PluginInfo(false, "LFSR", "Linear Feedback Shift Register", "LFSR/DetailedDescription/Description.xaml", "LFSR/Images/LFSR.png", "LFSR/Images/encrypt.png", "LFSR/Images/decrypt.png")]
28    [EncryptionType(EncryptionType.SymmetricBlock)]
29    public class LFSR : IThroughput
30    {
31        #region IPlugin Members
32
33        private LFSRSettings settings;
34        private String inputTapSequence;
35        private String inputSeed;
36        private CryptoolStream outputStream;
37        private String outputString;
38        private bool outputBool;
39        private bool inputClockBool = true;
40        private bool outputClockingBit;
41       
42        private LFSRPresentation lFSRPresentation;
43        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
44
45        #endregion
46
47        #region public variables
48
49        public bool stop = false;
50        public bool newSeed = true;
51        public String seedbuffer = null;
52        public String tapSequencebuffer = "1";
53        public Char outputbuffer = '0';
54        public bool lastInputPropertyWasBoolClock = false;
55
56        // for process()
57        public char[] tapSequenceCharArray = null;
58        public int seedBits = 1; // dummy value for compiler
59        public int actualRounds = 1; // dummy value for compiler
60        public Boolean myClock = true;
61        public char[] seedCharArray = null;
62        public int clocking;
63        public string outputStringBuffer = null;
64        public char outputBit;
65
66        #endregion
67
68        #region public interfaces
69
70        public LFSR()
71        {
72            this.settings = new LFSRSettings();
73            settings.PropertyChanged += settings_PropertyChanged;
74
75            lFSRPresentation = new LFSRPresentation();
76            Presentation = lFSRPresentation;
77            //lFSRPresentation.textBox0.TextChanged += textBox0_TextChanged;
78        }
79
80        void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
81        {
82            if (e.PropertyName == "InitLFSR")
83                preprocessingLFSR();
84            if (e.PropertyName == "SaveCurrentState")
85            {
86                if (settings.SaveCurrentState)
87                    settings.CurrentState = seedbuffer;
88                else
89                    settings.CurrentState = null;
90            }
91        }
92
93        public ISettings Settings
94        {
95            get { return (ISettings)this.settings; }
96            set { this.settings = (LFSRSettings)value; }
97        }
98
99        [PropertyInfo(Direction.InputData, "TapSequence", "TapSequence function in binary presentation.", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
100        public String InputTapSequence
101        {
102            [MethodImpl(MethodImplOptions.Synchronized)]
103            get { return inputTapSequence; }
104            [MethodImpl(MethodImplOptions.Synchronized)]
105            set
106            {
107                inputTapSequence = value;
108                OnPropertyChanged("InputTapSequence");
109                lastInputPropertyWasBoolClock = false;
110            }
111        }
112
113        [PropertyInfo(Direction.InputData, "Seed", "Seed of the LFSR in binary presentation.", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
114        public String InputSeed
115        {
116            [MethodImpl(MethodImplOptions.Synchronized)]
117            get { return inputSeed; }
118            [MethodImpl(MethodImplOptions.Synchronized)]
119            set
120            {
121                inputSeed = value;
122                OnPropertyChanged("InputSeed");
123                lastInputPropertyWasBoolClock = false;
124            }
125        }
126
127        [PropertyInfo(Direction.InputData, "Clock", "Optional clock input. LFSR only advances if clock is true.", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
128        public Boolean InputClockBool
129        {
130            [MethodImpl(MethodImplOptions.Synchronized)]
131            get { return inputClockBool; }
132            [MethodImpl(MethodImplOptions.Synchronized)]
133            set
134            {
135                inputClockBool = value;
136                OnPropertyChanged("InputClockBool");
137                lastInputPropertyWasBoolClock = true;
138            }
139        }
140
141        /*[PropertyInfo(Direction.OutputData, "Output stream", "LFSR Stream Output. Use this for bulk output.", "", false, true, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
142        public CryptoolStream OutputStream
143        {
144            //[MethodImpl(MethodImplOptions.Synchronized)]
145            get
146            {
147                if (this.outputStream != null)
148                {
149                    CryptoolStream cs = new CryptoolStream();
150                    listCryptoolStreamsOut.Add(cs);
151                    cs.OpenRead(this.outputStream.FileName);
152                    return cs;
153                }
154                return null;
155            }
156            //[MethodImpl(MethodImplOptions.Synchronized)]
157            set
158            {
159                outputStream = value;
160                if (value != null) listCryptoolStreamsOut.Add(value);
161                OnPropertyChanged("OutputStream");
162            }
163        }*/
164
165        [PropertyInfo(Direction.OutputData, "String Output", "Produces the output bits as a string with length==rounds. Use this output without a clock input.", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
166        public String OutputString
167        {
168            get { return outputString; }
169            set
170            {
171                outputString = value.ToString();
172                OnPropertyChanged("OutputString");
173            }
174        }
175
176        [PropertyInfo(Direction.OutputData, "Boolean Output", "LFSR Boolean Output. Use this output together with a clock input.", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
177        public bool OutputBool
178        {
179            get { return outputBool; }
180            set
181            {
182                outputBool = (bool)value;
183                //OnPropertyChanged("OutputBool");
184            }
185        }
186
187        [PropertyInfo(Direction.OutputData, "Clocking Bit Output", "Clocking Bit Output.", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
188        public bool OutputClockingBit
189        {
190            get { return outputClockingBit; }
191            set
192            {
193                outputClockingBit = (bool)value;
194                OnPropertyChanged("OutputClockingBit");
195            }
196        }
197       
198        /*
199        private bool controllerOutput;
200        [ControllerProperty(Direction.Output, "Controller Output", "", DisplayLevel.Beginner)]
201        public object ControllerOutput
202        {
203            get { return controllerOutput; }
204            set { controllerOutput = (bool)value; }
205        }*/
206
207        public void Dispose()
208        {
209            try
210            {
211                stop = false;
212                outputStream = null;
213                outputString = null;
214                outputStringBuffer = null;
215                inputTapSequence = null;
216                inputSeed = null;
217                newSeed = true;
218                seedbuffer = "0";
219                tapSequencebuffer = "1";
220                outputbuffer = '0';
221                lastInputPropertyWasBoolClock = false;
222
223                // for process()
224                tapSequenceCharArray = null;
225                seedBits = 1; // dummy value for compiler
226                actualRounds = 1; // dummy value for compiler
227                myClock = true;
228                seedCharArray = null;
229
230                if (outputStream != null)
231                {
232                    outputStream.Flush();
233                    outputStream.Close();
234                    outputStream = null;
235                }
236                foreach (CryptoolStream stream in listCryptoolStreamsOut)
237                {
238                    stream.Close();
239                }
240                listCryptoolStreamsOut.Clear();
241            }
242            catch (Exception ex)
243            {
244                GuiLogMessage(ex.Message, NotificationLevel.Error);
245            }
246            this.stop = false;
247        }
248
249        #endregion
250
251        #region private functions
252
253        private int checkForInputTapSequence()
254        {
255            /*if ((settings.Polynomial == null || (settings.Polynomial != null && settings.Polynomial.Length == 0)))
256            {
257                // awaiting polynomial from input
258                GuiLogMessage("No feedback polynomial given in settings. Awaiting external input.", NotificationLevel.Info);
259            }
260            else
261            {
262                inputTapSequence = settings.Polynomial;
263                return 1;
264            }*/
265
266            if ((inputTapSequence == null || (inputTapSequence != null && inputTapSequence.Length == 0)) && (settings.Polynomial == null || (settings.Polynomial != null && settings.Polynomial.Length == 0)))
267            {
268                // create some input
269                String dummystring = "1011";
270                // this.inputTapSequence = new String();
271                inputTapSequence = dummystring;
272                // write a warning to the outside world
273                GuiLogMessage("WARNING - No TapSequence provided. Using dummy data (" + dummystring + ").", NotificationLevel.Warning);
274                return 1;
275            }
276            else
277            {
278                return 0;
279            }
280        }
281
282        private int checkForInputSeed()
283        {
284            /*if ((settings.Seed == null || (settings.Seed != null && settings.Seed.Length == 0)))
285            {
286                // awaiting seed from input
287                GuiLogMessage("No seed given in settings. Awaiting external input.", NotificationLevel.Info);
288            }
289            else
290            {
291                inputSeed = settings.Seed;
292                return 1;
293            }*/
294
295            if ((inputSeed == null || (inputSeed != null && inputSeed.Length == 0)) && (settings.Seed == null || (settings.Seed != null && settings.Seed.Length == 0)))
296            {
297                // create some input
298                String dummystring = "1010";
299                // this.inputSeed = new CryptoolStream();
300                inputSeed = dummystring;
301                // write a warning to the outside world
302                GuiLogMessage("WARNING - No Seed provided. Using dummy data (" + dummystring + ").", NotificationLevel.Warning);
303                return 1;
304            }
305            else
306            {
307                return 0;
308            }
309        }
310
311        // Function to make binary representation of polynomial
312        private String MakeBinary(String strPoly)
313        {
314            bool gotX = false;
315            // remove spaces
316            strPoly = strPoly.Replace(" ", "");
317
318            Regex gotXRegEx = new Regex("(\\+x\\+1)+$");
319            if (gotXRegEx.IsMatch(strPoly)) gotX = true;
320            // remove last '1'
321            strPoly = strPoly.Remove(strPoly.Length - 1, 1);
322            // remove all x
323            strPoly = strPoly.Replace("x", "");
324            // remove all ^
325            strPoly = strPoly.Replace("^", "");
326
327            // split in string array
328            string[] strPolySplit = strPoly.Split(new string[] { "+" }, StringSplitOptions.RemoveEmptyEntries);
329            // convert to integer
330            int[] intPolyInteger = new int[strPolySplit.Length];
331            for (int i = strPolySplit.Length - 1; i >= 0; i--)
332            {
333                intPolyInteger[i] = Convert.ToInt32(strPolySplit[i]);
334            }
335
336            string strPolyBinary = null;
337            if (strPoly.Length != 0)
338            {
339                Array.Sort(intPolyInteger);
340                int highestOne = intPolyInteger[intPolyInteger.Length - 1];
341
342                int j = intPolyInteger.Length - 1;
343                for (int i = highestOne; i > 1; i--)
344                {
345                    if (j < 0 && (i != 1 || i != 0)) strPolyBinary += 0;
346                    else if (intPolyInteger[j] == i)
347                    {
348                        strPolyBinary += 1;
349                        j--;
350                    }
351                    else strPolyBinary += 0;
352                }
353            }
354            if (gotX) strPolyBinary += 1;
355            else strPolyBinary += 0;
356
357            strPolyBinary = new String(ReverseOrder(strPolyBinary.ToCharArray()));
358            //GuiLogMessage("strPolyBinary is: " + strPolyBinary, NotificationLevel.Info);
359
360            return strPolyBinary;
361        }
362
363        // Function to test for LFSR Polnyomial
364        private bool IsPolynomial(String strPoly)
365        {
366            // delete spaces
367            strPoly = strPoly.Replace(" ", "");
368            //(x\^([2-9]|[0-9][0-9])\+)*[x]?([\+]?1){1}
369            Regex objPolynomial = new Regex("(x\\^([2-9]|[0-9][0-9])\\+)+[x]?([\\+]?1){1}");
370            Regex keinHoch0oder1 = new Regex("(x\\^[0-1]\\+)+");
371            return !keinHoch0oder1.IsMatch(strPoly) && objPolynomial.IsMatch(strPoly);
372        }
373
374        // Function to turn around tapSequence (01101 -> 10110)
375        private char[] ReverseOrder(char[] tapSequence)
376        {
377            //String tempString = new String(tapSequence);
378            //GuiLogMessage("tapSequence before = " + tempString, NotificationLevel.Info);
379            char[] tempCharArray = new char[tapSequence.Length];
380
381            int temp;
382            for (int j = tapSequence.Length - 1; j >= 0; j--)
383            {
384                temp = (j - tapSequence.Length + 1) % (tapSequence.Length);
385                if (temp < 0) temp *= -1;
386                //GuiLogMessage("temp = " + temp, NotificationLevel.Info);
387                tempCharArray[j] = tapSequence[temp];
388            }
389            //tempString = new String(tempCharArray);
390            //GuiLogMessage("tapSequence after = " + tempString, NotificationLevel.Info);
391            return tempCharArray;
392        }
393
394        private string BuildPolynomialFromBinary(char [] tapSequence)
395        {
396            string polynomial = "Feedback polynomial: \n";
397            char[] tempTapSequence = ReverseOrder(tapSequence);
398            int power;
399
400            //build polynomial
401            for (int i = 0; i < tapSequence.Length; i++)
402            {
403                power = (i - tapSequence.Length + 1) * -1 % tapSequence.Length + 1;
404                if (tempTapSequence[i] == '1')
405                {
406                    if (power == 1) polynomial += "x + ";
407                    else if (power != 0) polynomial += "x^" + power + " + ";
408                    //else polynomial += "1";
409                }
410            }
411            // add last "+1"
412            polynomial += "1";
413
414            return  polynomial;
415        }
416
417        #endregion
418
419        public void Execute()
420        {
421            //lFSRPresentation.DeleteAll(100);
422            processLFSR();
423        }
424
425        private void preprocessingLFSR()
426        {
427            if (checkForInputTapSequence() == 1) return;
428            if (checkForInputSeed() == 1) return;
429
430            /*if (inputSeed == null || (inputSeed != null && inputSeed.Length == 0))
431            {
432                GuiLogMessage("No Seed given. Aborting now.", NotificationLevel.Error);
433                if (!settings.UseBoolClock) inputClock.Close();
434                return;
435            }
436
437            if (inputTapSequence == null || (inputTapSequence != null && inputTapSequence.Length == 0))
438            {
439                GuiLogMessage("No TapSequence given. Aborting now.", NotificationLevel.Error);
440                if (!settings.UseBoolClock) inputClock.Close();
441                return;
442            }*/
443
444            // read tapSequence
445            if (settings.Polynomial == null || (settings.Polynomial != null && settings.Polynomial.Length == 0))
446                tapSequencebuffer = inputTapSequence;
447            else
448                tapSequencebuffer = settings.Polynomial;
449
450            //read seed
451            if (settings.CurrentState != null && settings.CurrentState.Length != 0)
452                seedbuffer = settings.CurrentState;
453            else if (settings.Seed == null || (settings.Seed != null && settings.Seed.Length == 0))
454                seedbuffer = inputSeed;
455            else
456                seedbuffer = settings.Seed;
457
458            // check if tapSequence is binary
459            bool tapSeqisBool = true;
460            foreach (char character in tapSequencebuffer)
461            {
462                if (character != '0' && character != '1')
463                {
464                    tapSeqisBool = false;
465                    //return;
466                }
467            }
468
469            // if tapSequence is not binary, await polynomial
470            if (!tapSeqisBool)
471            {
472                GuiLogMessage("TapSequence is not binary. Awaiting polynomial.", NotificationLevel.Info);
473                if (IsPolynomial(tapSequencebuffer))
474                {
475                    GuiLogMessage(tapSequencebuffer + " is a valid polynomial.", NotificationLevel.Info);
476                    tapSequencebuffer = MakeBinary(tapSequencebuffer);
477                    GuiLogMessage("Polynomial in binary form: " + tapSequencebuffer, NotificationLevel.Info);
478
479                    // check if polynomial has false length
480                    if (tapSequencebuffer.Length != seedbuffer.Length)
481                    {
482                        /*// check if its too long
483                        if (inputSeed.Length - tapSequencebuffer.Length < 0)
484                        {
485                            GuiLogMessage("ERROR - Your polynomial " + tapSequencebuffer + " is TOO LONG (" + tapSequencebuffer.Length + " Bits) for your seed. Aborting now.", NotificationLevel.Error);
486                            if (!settings.UseBoolClock) inputClock.Close();
487                            return;
488                        }
489                        // seems to be too short, so fill it with zeros at the beginning
490                        else
491                        {
492                            for (int j = inputSeed.Length - tapSequencebuffer.Length; j > 0; j--)
493                            {
494                                tapSequencebuffer = "0" + tapSequencebuffer;
495                            }
496                        }*/
497                        GuiLogMessage("ERROR - Your polynomial " + tapSequencebuffer + " has to be the same length (" + tapSequencebuffer.Length + " Bits) as your seed (" + seedbuffer.Length + " Bits). Aborting now.", NotificationLevel.Error);
498                        Dispose();
499                        return;
500                    }
501
502                    //GuiLogMessage("Polynomial after length fitting: " + tapSequencebuffer, NotificationLevel.Info);
503                }
504                else
505                {
506                    GuiLogMessage("ERROR - " + tapSequencebuffer + " is NOT a valid polynomial. Aborting now.", NotificationLevel.Error);
507                    //Console.WriteLine("\n{0} is NOT a valid polynomial.", tapSequencebuffer);
508                    Dispose();
509                    return;
510                }
511            }
512
513            // convert tapSequence into char array
514            //tapSequenceCharArray = ReverseOrder(tapSequencebuffer.ToCharArray());
515            tapSequenceCharArray = tapSequencebuffer.ToCharArray();
516
517            if (tapSequencebuffer.Length != seedbuffer.Length)
518            {
519                // stop, because seed and tapSequence must have same length
520                GuiLogMessage("ERROR - Seed and tapSequence must have same length. Aborting now.", NotificationLevel.Error);
521                Dispose();
522                return;
523            }
524
525            int tapSequenceBits = tapSequencebuffer.Length;
526            seedBits = seedbuffer.Length;
527
528            GuiLogMessage("inputTapSequence length [bits]: " + tapSequenceBits.ToString(), NotificationLevel.Debug);
529            GuiLogMessage("inputSeed length [bits]: " + seedBits.ToString(), NotificationLevel.Debug);
530
531            //check if last tap is 1, otherwise stop
532            if (tapSequenceCharArray[tapSequenceCharArray.Length - 1] == '0')
533            {
534                GuiLogMessage("ERROR - Last tap of tapSequence must be 1. Aborting now.", NotificationLevel.Error);
535                return;
536            }
537
538            // convert seed into char array
539            seedCharArray = seedbuffer.ToCharArray();
540
541            // check if seed is binary
542            foreach (char character in seedCharArray)
543            {
544                if (character != '0' && character != '1')
545                {
546                    GuiLogMessage("ERROR 0 - Seed has to be binary. Aborting now. Character is: " + character, NotificationLevel.Error);
547                    return;
548                }
549            }
550            if (settings.UseAdditionalOutputBit)
551            {
552                if (settings.ClockingBit < seedCharArray.Length) clocking = (seedCharArray.Length - settings.ClockingBit - 1);
553                else
554                {
555                    clocking = -1;
556                    GuiLogMessage("WARNING: Clocking Bit is too high. Ignored.", NotificationLevel.Warning);
557                }
558
559            }
560            else clocking = -1;
561
562            /*// check which clock to use
563            if (settings.UseBoolClock)
564            {
565                myClock = inputClockBool;
566            }
567            else if (!settings.UseBoolClock)
568            {
569                // read stream clock
570                checkForInputClock();
571                inputClock.OpenWrite("LFSR Restart");
572                String stringClock = inputClock.ReadByte().ToString();
573                inputClock.Position = 0;
574                if (String.Equals(stringClock, "49")) myClock = true; else myClock = false;
575                //inputClock.Close();
576            }*/
577
578            // check if Rounds are given
579            int defaultRounds = 10;
580
581            // check if Rounds in settings are given and use them only if no bool clock is selected
582            if (!settings.UseBoolClock)
583            {
584                if (settings.Rounds == 0) actualRounds = defaultRounds; else actualRounds = settings.Rounds;
585            }
586            else actualRounds = 1;
587
588            // draw LFSR Quickwatch
589            if (!settings.NoQuickwatch)
590            {
591                lFSRPresentation.DeleteAll(100);
592                lFSRPresentation.DrawLFSR(seedCharArray, tapSequenceCharArray, clocking);
593                lFSRPresentation.FillBoxes(seedCharArray, tapSequenceCharArray, ' ', BuildPolynomialFromBinary(tapSequenceCharArray));
594            }
595        }
596
597        private void processLFSR()
598        {
599            // check if event was from the boolean clock input
600            // if so, check if boolean clock should be used
601            // if not, do not process LFSR
602            if (lastInputPropertyWasBoolClock)
603            {
604                if (!settings.UseBoolClock) return;
605                //GuiLogMessage("First if.", NotificationLevel.Info);
606            }
607                // if last event wasn't from the clock but clock shall be
608                // the only event to start from, do not go on
609            else
610            {
611                // do nothing if we should use bool clock, but become event from other inputs
612                if (settings.UseBoolClock) return;
613                //GuiLogMessage("Second if.", NotificationLevel.Info);
614            }
615            // process LFSR
616           
617            try
618            {
619                /*char[] tapSequenceCharArray = null;
620                int seedBits = 1; // dummy value for compiler
621                int actualRounds = 1; // dummy value for compiler
622                Boolean myClock = true;
623                char[] seedCharArray = null;
624
625                // open output stream
626                outputStream = new CryptoolStream();
627                listCryptoolStreamsOut.Add(outputStream);
628                outputStream.OpenWrite(this.GetPluginInfoAttribute().Caption);
629                */
630
631                // make all this stuff only one time at the beginning of our chainrun
632                if (newSeed)
633                {
634                    preprocessingLFSR();
635                }
636               
637                // Here we go!
638                // check which clock to use
639                if (settings.UseBoolClock)
640                {
641                    myClock = inputClockBool;
642                }
643                else if (!settings.UseBoolClock)
644                {
645                    myClock = true;
646                }
647
648                // (re-)draw LFSR Quickwatch
649                if (!settings.NoQuickwatch)
650                {
651                    lFSRPresentation.DeleteAll(100);
652                    lFSRPresentation.DrawLFSR(seedCharArray, tapSequenceCharArray, clocking);
653                }
654
655                // open output stream
656                outputStream = new CryptoolStream();
657                listCryptoolStreamsOut.Add(outputStream);
658                outputStream.OpenWrite();
659
660                //GuiLogMessage("Action is: Now!", NotificationLevel.Debug);
661                DateTime startTime = DateTime.Now;
662
663                //////////////////////////////////////////////////////
664                // compute LFSR //////////////////////////////////////
665                //////////////////////////////////////////////////////
666                GuiLogMessage("Starting computation", NotificationLevel.Debug);
667               
668                int i = 0;
669               
670                for (i = 0; i < actualRounds; i++)
671                {
672                    // compute only if clock = 1 or true
673                    if (myClock)
674                    {
675                        StatusChanged((int)LFSRImage.Encode);
676
677                        // make bool output
678                        if (seedCharArray[seedBits - 1] == '0') outputBool = false;
679                        else outputBool = true;
680                        //GuiLogMessage("OutputBool is: " + outputBool.ToString(), NotificationLevel.Info);
681
682                        // write last bit to output buffer, output stream buffer, stream and bool
683                        outputbuffer = seedCharArray[seedBits - 1];
684                        outputStream.Write((Byte)outputbuffer);
685                        outputStringBuffer += seedCharArray[seedBits - 1];
686
687                        // update outputs
688                        OnPropertyChanged("OutputBool");
689                        OnPropertyChanged("OutputStream");
690
691                        // shift seed array
692                        char newBit = '0';
693
694                        // compute new bit
695                        bool firstDone = false;
696                        for (int j = 0; j < seedBits; j++)
697                        {
698                            // check if tapSequence is 1
699                            if (tapSequenceCharArray[j] == '1')
700                            {
701                                // if it is the first one, just take it
702                                if (!firstDone)
703                                {
704                                    newBit = seedCharArray[j];
705                                    firstDone = true;
706                                }
707                                // or do an XOR with the last computed bit
708                                else
709                                {
710                                    newBit = (newBit ^ seedCharArray[j]).ToString()[0];
711                                }
712                            }
713                        }
714                        // keep output bit for presentation
715                        outputBit = seedCharArray[seedBits - 1];
716
717                        // shift seed array
718                        for (int j = seedBits - 1; j > 0; j--)
719                        {
720                            seedCharArray[j] = seedCharArray[j - 1];
721                            //GuiLogMessage("seedCharArray[" + j + "] is: " + seedCharArray[j], NotificationLevel.Info);
722                        }
723                        seedCharArray[0] = newBit;
724
725                        //update quickwatch presentation
726                        if (!settings.NoQuickwatch)
727                        {
728                            lFSRPresentation.FillBoxes(seedCharArray, tapSequenceCharArray, outputBit, BuildPolynomialFromBinary(tapSequenceCharArray));
729                        }
730
731                        // write current "seed" back to seedbuffer
732                        seedbuffer = null;
733                        foreach (char c in seedCharArray) seedbuffer += c;
734
735                        //GuiLogMessage("New Bit: " + newBit.ToString(), NotificationLevel.Info);
736                    }
737                    else
738                    {
739                        StatusChanged((int)LFSRImage.Decode);
740
741                        if (settings.AlwaysCreateOutput)
742                        {
743                           
744                            // make bool output = 0 if it is the first round
745                            if (newSeed)
746                            {
747                                outputBool = false;
748                                outputbuffer = '0';
749                            }
750                            else
751                            {
752                                if (outputBit == '0')
753                                    outputBool = false;
754                                else
755                                    outputBool = true;
756                                outputbuffer = outputBit;
757                            }
758                            //GuiLogMessage("OutputBool is: " + outputBool.ToString(), NotificationLevel.Info);
759
760                            // write bit to output buffer, stream and bool
761                           
762                            outputStream.Write((Byte)outputbuffer);
763                            OnPropertyChanged("OutputBool");
764                            OnPropertyChanged("OutputStream");
765
766                            // update quickwatch presentation
767                            if (!settings.NoQuickwatch)
768                            {
769                                lFSRPresentation.FillBoxes(seedCharArray, tapSequenceCharArray, outputbuffer, BuildPolynomialFromBinary(tapSequenceCharArray));
770                            }
771
772                        }
773                        else
774                        {
775                            // update quickwatch with current state but without any output bit
776                            if (!settings.NoQuickwatch)
777                            {
778                                lFSRPresentation.FillBoxes(seedCharArray, tapSequenceCharArray, ' ', BuildPolynomialFromBinary(tapSequenceCharArray));
779                            }
780                        }
781                    }
782                    // in both cases update additional output bit if set in settings
783                    if (settings.UseAdditionalOutputBit)
784                    {
785                        // make clocking bit output only if its not out of bounds
786                        if (clocking != -1)
787                        {
788                            if (seedCharArray[clocking] == '0') outputClockingBit = false;
789                            else outputClockingBit = true;
790                            OnPropertyChanged("OutputClockingBit");
791                        }
792                    }
793
794                    // reset newSeed
795                    newSeed = false;
796                }
797
798                //controllerOutput = true;
799                //OnPropertyChanged("ControllerOutput");
800
801                // stop counter
802                DateTime stopTime = DateTime.Now;
803                // compute overall time
804                TimeSpan duration = stopTime - startTime;
805
806                if (!stop)
807                {
808                    // finally write output string
809                    outputString = outputStringBuffer;
810                    OnPropertyChanged("OutputString");
811
812                    GuiLogMessage("Complete!", NotificationLevel.Debug);
813
814                    GuiLogMessage("Time used: " + duration, NotificationLevel.Debug);
815                    outputStream.Close();
816                    OnPropertyChanged("OutputStream");
817                }
818
819                if (stop)
820                {
821                    outputStream.Close();
822                    outputStringBuffer = null;
823                    GuiLogMessage("Aborted!", NotificationLevel.Debug);
824                }
825            }
826            catch (Exception exception)
827            {
828                GuiLogMessage(exception.Message, NotificationLevel.Error);
829            }
830            finally
831            {
832                ProgressChanged(1, 1);
833            }
834        }
835
836        #region events and stuff
837
838        public void Initialize()
839        {
840        }
841
842        public event StatusChangedEventHandler OnPluginStatusChanged;
843
844        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
845        private void GuiLogMessage(string message, NotificationLevel logLevel)
846        {
847            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
848        }
849
850        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
851        private void ProgressChanged(double value, double max)
852        {
853            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
854        }
855
856        public void Pause()
857        {
858        }
859
860        public void PostExecution()
861        {
862            if (settings.SaveCurrentState)
863                settings.CurrentState = seedbuffer;
864            else
865                settings.CurrentState = null;
866            Dispose();
867        }
868
869        public void PreExecution()
870        {
871            Dispose();
872        }
873
874        public void Stop()
875        {
876            StatusChanged((int)LFSRImage.Default);
877            newSeed = true;
878            stop = true;
879        }
880
881        public UserControl Presentation { get; private set; }
882
883        public UserControl QuickWatchPresentation
884        {
885            get { return Presentation; }
886        }
887
888        #endregion
889
890        #region INotifyPropertyChanged Members
891
892        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
893
894        public void OnPropertyChanged(string name)
895        {
896            //EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
897            if (PropertyChanged != null)
898            {
899              PropertyChanged(this, new PropertyChangedEventArgs(name));
900            }
901        }
902
903        private void StatusChanged(int imageIndex)
904        {
905            EventsHelper.StatusChanged(OnPluginStatusChanged, this, new StatusEventArgs(StatusChangedMode.ImageUpdate, imageIndex));
906        }
907
908        #endregion
909    }
910
911    #region Image
912
913    enum LFSRImage
914    {
915        Default,
916        Encode,
917        Decode
918    }
919
920    #endregion
921}
Note: See TracBrowser for help on using the repository browser.