Statistics
| Branch: | Revision:

root / trunk / hammock / src / net35 / ICSharpCode.SharpZipLib.Silverlight / Checksums / CRC32.cs @ 0eea575a

History | View | Annotate | Download (12.2 kB)

1
// CRC32.cs - Computes CRC32 data checksum of a data stream
2
// Copyright (C) 2001 Mike Krueger
3
//
4
// This file was translated from java, it was part of the GNU Classpath
5
// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
6
//
7
// This program is free software; you can redistribute it and/or
8
// modify it under the terms of the GNU General Public License
9
// as published by the Free Software Foundation; either version 2
10
// of the License, or (at your option) any later version.
11
//
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
// GNU General Public License for more details.
16
//
17
// You should have received a copy of the GNU General Public License
18
// along with this program; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
//
21
// Linking this library statically or dynamically with other modules is
22
// making a combined work based on this library.  Thus, the terms and
23
// conditions of the GNU General Public License cover the whole
24
// combination.
25
// 
26
// As a special exception, the copyright holders of this library give you
27
// permission to link this library with independent modules to produce an
28
// executable, regardless of the license terms of these independent
29
// modules, and to copy and distribute the resulting executable under
30
// terms of your choice, provided that you also meet, for each linked
31
// independent module, the terms and conditions of the license of that
32
// module.  An independent module is a module which is not derived from
33
// or based on this library.  If you modify this library, you may extend
34
// this exception to your version of the library, but you are not
35
// obligated to do so.  If you do not wish to do so, delete this
36
// exception statement from your version.
37

    
38
using System;
39

    
40
namespace ICSharpCode.SharpZipLib.Silverlight.Checksums
41
{
42
    /// <summary>
43
    /// Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
44
    /// x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
45
    ///
46
    /// Polynomials over GF(2) are represented in binary, one bit per coefficient,
47
    /// with the lowest powers in the most significant bit.  Then adding polynomials
48
    /// is just exclusive-or, and multiplying a polynomial by x is a right shift by
49
    /// one.  If we call the above polynomial p, and represent a byte as the
50
    /// polynomial q, also with the lowest power in the most significant bit (so the
51
    /// byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
52
    /// where a mod b means the remainder after dividing a by b.
53
    ///
54
    /// This calculation is done using the shift-register method of multiplying and
55
    /// taking the remainder.  The register is initialized to zero, and for each
56
    /// incoming bit, x^32 is added mod p to the register if the bit is a one (where
57
    /// x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
58
    /// x (which is shifting right by one and adding x^32 mod p if the bit shifted
59
    /// out is a one).  We start with the highest power (least significant bit) of
60
    /// q and repeat for all eight bits of q.
61
    ///
62
    /// The table is simply the CRC of all possible eight bit values.  This is all
63
    /// the information needed to generate CRC's on data a byte at a time for all
64
    /// combinations of CRC register values and incoming bytes.
65
    /// </summary>
66
    public sealed class Crc32 : IChecksum
67
    {
68
        private const uint CrcSeed = 0xFFFFFFFF;
69
		
70
        readonly static uint[] CrcTable = new uint[] {
71
                                                         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,
72
                                                         0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,
73
                                                         0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07,
74
                                                         0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
75
                                                         0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856,
76
                                                         0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
77
                                                         0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
78
                                                         0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
79
                                                         0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
80
                                                         0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,
81
                                                         0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599,
82
                                                         0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
83
                                                         0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190,
84
                                                         0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
85
                                                         0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E,
86
                                                         0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
87
                                                         0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
88
                                                         0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
89
                                                         0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
90
                                                         0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
91
                                                         0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
92
                                                         0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
93
                                                         0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010,
94
                                                         0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
95
                                                         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17,
96
                                                         0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,
97
                                                         0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
98
                                                         0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
99
                                                         0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344,
100
                                                         0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
101
                                                         0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A,
102
                                                         0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
103
                                                         0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1,
104
                                                         0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
105
                                                         0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
106
                                                         0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
107
                                                         0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE,
108
                                                         0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
109
                                                         0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C,
110
                                                         0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
111
                                                         0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
112
                                                         0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
113
                                                         0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1,
114
                                                         0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
115
                                                         0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
116
                                                         0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
117
                                                         0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66,
118
                                                         0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
119
                                                         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
120
                                                         0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,
121
                                                         0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
122
                                                         0x2D02EF8D
123
                                                     };
124
		
125
        internal static uint ComputeCrc32(uint oldCrc, byte value)
126
        {
127
            return CrcTable[(oldCrc ^ value) & 0xFF] ^ (oldCrc >> 8);
128
        }
129
		
130
        /// <summary>
131
        /// The crc data checksum so far.
132
        /// </summary>
133
        uint crc;
134
		
135
        /// <summary>
136
        /// Returns the CRC32 data checksum computed so far.
137
        /// </summary>
138
        public long Value {
139
            get {
140
                return crc;
141
            }
142
            set {
143
                crc = (uint)value;
144
            }
145
        }
146
		
147
        /// <summary>
148
        /// Resets the CRC32 data checksum as if no update was ever called.
149
        /// </summary>
150
        public void Reset() 
151
        { 
152
            crc = 0; 
153
        }
154
		
155
        /// <summary>
156
        /// Updates the checksum with the int bval.
157
        /// </summary>
158
        /// <param name = "value">
159
        /// the byte is taken as the lower 8 bits of value
160
        /// </param>
161
        public void Update(int value)
162
        {
163
            crc ^= CrcSeed;
164
            crc  = CrcTable[(crc ^ value) & 0xFF] ^ (crc >> 8);
165
            crc ^= CrcSeed;
166
        }
167
		
168
        /// <summary>
169
        /// Updates the checksum with the bytes taken from the array.
170
        /// </summary>
171
        /// <param name="buffer">
172
        /// buffer an array of bytes
173
        /// </param>
174
        public void Update(byte[] buffer)
175
        {
176
            if (buffer == null) {
177
                throw new ArgumentNullException("buffer");
178
            }
179
			
180
            Update(buffer, 0, buffer.Length);
181
        }
182
		
183
        /// <summary>
184
        /// Adds the byte array to the data checksum.
185
        /// </summary>
186
        /// <param name = "buffer">
187
        /// The buffer which contains the data
188
        /// </param>
189
        /// <param name = "offset">
190
        /// The offset in the buffer where the data starts
191
        /// </param>
192
        /// <param name = "count">
193
        /// The number of data bytes to update the CRC with.
194
        /// </param>
195
        public void Update(byte[] buffer, int offset, int count)
196
        {
197
            if (buffer == null) {
198
                throw new ArgumentNullException("buffer");
199
            }
200
			
201
            if ( count < 0 ) {
202
                throw new ArgumentOutOfRangeException("count", "Count cannot be less than zero");
203
            }
204
			
205
            if (offset < 0 || offset + count > buffer.Length) {
206
                throw new ArgumentOutOfRangeException("offset");
207
            }
208
			
209
            crc ^= CrcSeed;
210
			
211
            while (--count >= 0) {
212
                crc = CrcTable[(crc ^ buffer[offset++]) & 0xFF] ^ (crc >> 8);
213
            }
214
			
215
            crc ^= CrcSeed;
216
        }
217
    }
218
}