source: trunk/CrypPlugins/CRC/CRC.cs @ 2411

Last change on this file since 2411 was 2334, checked in by Matthäus Wander, 11 years ago

removed 1006 occurences of DisplayLevel in 218 files (see #122)

File size: 9.5 KB
Line 
1/*
2   Copyright 2009 Matthäus Wander, University of Duisburg-Essen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Collections.Generic;
19using System.Linq;
20using System.Text;
21using System.ComponentModel;
22
23using Cryptool.PluginBase;
24using Cryptool.PluginBase.Cryptography;
25using Cryptool.PluginBase.IO;
26using Cryptool.PluginBase.Miscellaneous;
27
28/*
29 * CRC hash algorithm (currently just CRC-32).
30 *
31 * TODO/Wishlist:
32 * - add support for other generator polynoms and hash lengths.
33 *
34 * The CRC-32 algorithm implementation is based on a code snippet by NullFX with the following license:
35 *
36 * ******************************************************
37 * *          NULLFX FREE SOFTWARE LICENSE              *
38 * ******************************************************
39 * *  CRC32 Library                                     *
40 * *  by: Steve Whitley                                 *
41 * *  © 2005 NullFX Software                            *
42 * *                                                    *
43 * * NULLFX SOFTWARE DISCLAIMS ALL WARRANTIES,          *
44 * * RESPONSIBILITIES, AND LIABILITIES ASSOCIATED WITH  *
45 * * USE OF THIS CODE IN ANY WAY, SHAPE, OR FORM        *
46 * * REGARDLESS HOW IMPLICIT, EXPLICIT, OR OBSCURE IT   *
47 * * IS. IF THERE IS ANYTHING QUESTIONABLE WITH REGARDS *
48 * * TO THIS SOFTWARE BREAKING AND YOU GAIN A LOSS OF   *
49 * * ANY NATURE, WE ARE NOT THE RESPONSIBLE PARTY. USE  *
50 * * OF THIS SOFTWARE CREATES ACCEPTANCE OF THESE TERMS *
51 * *                                                    *
52 * * USE OF THIS CODE MUST RETAIN ALL COPYRIGHT NOTICES *
53 * * AND LICENSES (MEANING THIS TEXT).                  *
54 * *                                                    *
55 * ******************************************************
56 */
57namespace Cryptool.CRC
58{
59    [Author("Matthäus Wander", "wander@cryptool.org", "Fachgebiet Verteilte Systeme, Universität Duisburg-Essen", "http://www.vs.uni-due.de")]
60    [PluginInfo(false, "CRC32", "Cyclic Redundancy Check 32-Bit", null, "CRC/icon.png")]
61    public class CRC : ICheckSumHash
62    {
63        #region Constants and private variables
64
65        const int BUFSIZE = 1024;
66
67        private ISettings settings = new CRCSettings();
68        private CryptoolStream inputData;
69        private byte[] outputData;
70        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
71
72        private uint[] table;
73
74        #endregion
75
76        #region Public interface
77
78        public CRC()
79        {
80        }
81
82        public ISettings Settings
83        {
84            get { return settings; }
85            set { settings = value; }
86        }
87
88        [PropertyInfo(Direction.InputData, "Input stream", "Input data to be hashed", "", true, false, QuickWatchFormat.Hex, null)]
89        public CryptoolStream InputData
90        {
91            get
92            {
93                if (inputData == null) { return null; }
94
95                GuiLogMessage("Filename of input stream: " + inputData.FileName, NotificationLevel.Debug);
96
97                CryptoolStream cs = new CryptoolStream();
98                cs.OpenRead(inputData.FileName);
99                listCryptoolStreamsOut.Add(cs);
100                return cs;
101            }
102            set
103            {
104                inputData = value;
105                OnPropertyChanged("InputData");
106            }
107        }
108
109        [PropertyInfo(Direction.OutputData, "Hash value", "Output hash value as byte array", "", false, false, QuickWatchFormat.Hex, null)]
110        public byte[] OutputData
111        {
112            get
113            {
114                if (outputData == null) { return null; }
115
116                GuiLogMessage("Got request for hash (byte array)", NotificationLevel.Debug);
117                return outputData;
118            }
119            set
120            {
121            }
122        }
123
124        [PropertyInfo(Direction.OutputData, "Hash value", "Output hash value as Stream", "", false, false, QuickWatchFormat.Hex, null)]
125        public CryptoolStream OutputDataStream
126        {
127            get
128            {
129                if (outputData == null) { return null; }
130
131                CryptoolStream cs = new CryptoolStream();
132                listCryptoolStreamsOut.Add(cs);
133                cs.OpenRead(this.GetPluginInfoAttribute().Caption, outputData);
134                GuiLogMessage("Got request for hash (stream)", NotificationLevel.Debug);
135                return cs;
136            }
137            set
138            {
139            }
140        }
141
142        #endregion
143
144        #region IPlugin Members
145
146        public void Dispose()
147        {
148            if (inputData != null)
149            {
150                inputData.Close();
151                inputData = null;
152            }
153
154            foreach (CryptoolStream cs in listCryptoolStreamsOut)
155            {
156                cs.Close();
157            }
158        }
159
160        public void Execute()
161        {
162            ProgressChanged(0.0, 1.0);
163
164            if (inputData == null)
165            {
166                GuiLogMessage("Received null value for input CryptoolStream, not processing.", NotificationLevel.Warning);
167                return;
168            }
169
170            byte[] input = new byte[BUFSIZE];
171            uint crc = 0xffffffff;
172            int readCount;
173
174            // read and process 1024 bytes long portions of input stream
175            for(long bytesLeft = inputData.Length - inputData.Position; inputData.Position < inputData.Length; bytesLeft -= readCount)
176            {
177                ProgressChanged((double)inputData.Position / inputData.Length, 1.0);
178                readCount = bytesLeft < input.Length ? (int)bytesLeft : input.Length;
179                GuiLogMessage("Trying to fill working buffer with " + readCount + " bytes", NotificationLevel.Debug);
180                readCount = inputData.Read(input, 0, readCount);
181
182                for (int i = 0; i < readCount; ++i)
183                {
184                    byte index = (byte)(((crc) & 0xff) ^ input[i]);
185                    crc = (uint)((crc >> 8) ^ table[index]);
186                }
187            }
188
189            crc ^= 0xffffffff;
190
191            outputData = new byte[4];
192
193            outputData[0] = (byte)(crc >> 24);
194            outputData[1] = (byte)(crc >> 16);
195            outputData[2] = (byte)(crc >> 8);
196            outputData[3] = (byte)(crc);
197
198            ProgressChanged(1.0, 1.0);
199            GuiLogMessage("CRC calculation has finished", NotificationLevel.Debug);
200
201            OnPropertyChanged("OutputData");
202            OnPropertyChanged("OutputDataStream");
203        }
204
205        /// <summary>
206        /// This methods builds the lookup table depending on generator polynom to allow a fast hashing implementation.
207        /// </summary>
208        public void Initialize()
209        {
210            uint poly = 0xEDB88320; // reversed presentation of polynom 0x04C11DB7
211
212            // build lookup table
213            table = new uint[256];
214            uint temp = 0;
215            for (uint i = 0; i < table.Length; ++i)
216            {
217                temp = i;
218                for (int j = 8; j > 0; --j)
219                {
220                    if ((temp & 1) == 1)
221                    {
222                        temp = (uint)((temp >> 1) ^ poly);
223                    }
224                    else
225                    {
226                        temp >>= 1;
227                    }
228                }
229                table[i] = temp;
230            }
231        }
232
233        public void Pause()
234        {
235        }
236
237        public void PostExecution()
238        {
239            Dispose();
240        }
241
242        public void PreExecution()
243        {
244        }
245
246        public System.Windows.Controls.UserControl Presentation
247        {
248            get { return null; }
249        }
250
251        public System.Windows.Controls.UserControl QuickWatchPresentation
252        {
253            get { return null; }
254        }
255
256        public void Stop()
257        {
258        }
259
260        #endregion
261
262        #region INotifyPropertyChanged Members
263
264        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
265        private void ProgressChanged(double value, double max)
266        {
267            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
268        }
269
270        public event StatusChangedEventHandler OnPluginStatusChanged;
271
272        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
273        private void OnPropertyChanged(string p)
274        {
275            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(p));
276        }
277
278        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
279        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
280        {
281            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
282        }
283
284        #endregion
285    }
286}
Note: See TracBrowser for help on using the repository browser.