source: trunk/CrypPlugins/MD5Collider/Algorithm/MultiThreadedMD5Collider.cs @ 1356

Last change on this file since 1356 was 1356, checked in by pretzsch, 11 years ago

o FIX MD5Collider: Prevention of race condition occuring when collision search has finished

File size: 5.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.ComponentModel;
6using System.Timers;
7
8namespace Cryptool.Plugins.MD5Collider.Algorithm
9{
10    class MultiThreadedMD5Collider<T> : IMD5ColliderAlgorithm where T : IMD5ColliderAlgorithm, new()
11    {
12        private List<ColliderWorkerAdapter<T>> workers = new List<ColliderWorkerAdapter<T>>();
13        private List<IMD5ColliderAlgorithm> colliders = new List<IMD5ColliderAlgorithm>();
14        private IMD5ColliderAlgorithm successfulCollider;
15        private Timer progressUpdateTimer;
16        private int workerCount;
17
18        private System.Threading.AutoResetEvent finishedEvent = new System.Threading.AutoResetEvent(false);
19
20        public MultiThreadedMD5Collider()
21        {
22            workerCount = Math.Max(Environment.ProcessorCount, 1);
23
24            for (int i = 0; i < workerCount; i++)
25            {
26                IMD5ColliderAlgorithm collider = new T();
27                colliders.Add(collider);
28
29                ColliderWorkerAdapter<T> colliderWorkerAdapter = new ColliderWorkerAdapter<T>(this, collider);
30                workers.Add(colliderWorkerAdapter);
31            }
32
33            progressUpdateTimer = new Timer();
34            progressUpdateTimer.Interval = 250;
35            progressUpdateTimer.Elapsed += progressUpdateTimer_Tick;
36        }
37
38        public byte[] FirstCollidingData { get { return successfulCollider != null ? successfulCollider.FirstCollidingData : null; } }
39        public byte[] SecondCollidingData { get { return successfulCollider != null ? successfulCollider.SecondCollidingData : null; } }
40
41        public byte[] RandomSeed
42        {
43            set
44            {
45                if (value == null)
46                {
47                    foreach (IMD5ColliderAlgorithm collider in colliders)
48                        collider.RandomSeed = null;
49                    return;
50                }
51
52
53                byte[] randomSeedCopy = (byte[])value.Clone();
54
55                foreach (IMD5ColliderAlgorithm collider in colliders)
56                {
57                    collider.RandomSeed = randomSeedCopy;
58
59                    randomSeedCopy = (byte[])randomSeedCopy.Clone();
60
61                    if (randomSeedCopy.Length == 0)
62                        randomSeedCopy = new byte[1];
63
64                    randomSeedCopy[0]++;
65                }
66            }
67        }
68
69        private Object finishedLock = new Object();
70
71        internal void SignalWorkIsFinished(IMD5ColliderAlgorithm successfulCollider)
72        {
73            lock (finishedLock)
74            {
75                if (this.successfulCollider == null)
76                {
77                    this.successfulCollider = successfulCollider;
78                    updateProgress();
79                    Stop();
80
81                    finishedEvent.Set();
82                }
83            }
84        }
85
86        public byte[] IHV
87        {
88            set
89            {
90                foreach (IMD5ColliderAlgorithm collider in colliders)
91                    collider.IHV = value;
92            }
93        }
94
95        public int MatchProgressMax
96        {
97            get { return colliders.Max(c => c.MatchProgressMax); }
98        }
99
100        public int MatchProgress
101        {
102            get { return colliders.Max(c => c.MatchProgress); }
103            set { }
104        }
105
106        public long CombinationsTried
107        {
108            get { return colliders.Sum(c => c.CombinationsTried); }
109        }
110
111        public TimeSpan ElapsedTime
112        {
113            get { return colliders.Max(c => c.ElapsedTime); }
114        }
115
116        public void FindCollision()
117        {
118            progressUpdateTimer.Start();
119
120            finishedEvent.Reset();
121            successfulCollider = null;
122
123            foreach (ColliderWorkerAdapter<T> worker in workers)
124                worker.StartWork();
125
126            finishedEvent.WaitOne();
127
128            OnPropertyChanged("FirstCollidingData");
129            OnPropertyChanged("SecondCollidingData");
130        }
131
132        public void Stop()
133        {
134            foreach (IMD5ColliderAlgorithm collider in colliders)
135                collider.Stop();
136
137            progressUpdateTimer.Stop();
138        }
139
140        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
141        private void OnPropertyChanged(string propertyName)
142        {
143            if (PropertyChanged != null)
144                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
145        }
146
147
148        void progressUpdateTimer_Tick(object sender, EventArgs e)
149        {
150            updateProgress();
151        }
152
153        private void updateProgress()
154        {
155            OnPropertyChanged("MatchProgressMax");
156            OnPropertyChanged("MatchProgress");
157            OnPropertyChanged("CombinationsTried");
158            OnPropertyChanged("ElapsedTime");
159        }
160    }
161}
Note: See TracBrowser for help on using the repository browser.