New test.
[mono.git] / mcs / class / Compat.ICSharpCode.SharpZipLib / ICSharpCode.SharpZipLib / Checksums / Crc32.cs
1 // CRC32.cs - Computes CRC32 data checksum of a data stream\r
2 // Copyright (C) 2001 Mike Krueger\r
3 //\r
4 // This file was translated from java, it was part of the GNU Classpath\r
5 // Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.\r
6 //\r
7 // This program is free software; you can redistribute it and/or\r
8 // modify it under the terms of the GNU General Public License\r
9 // as published by the Free Software Foundation; either version 2\r
10 // of the License, or (at your option) any later version.\r
11 //\r
12 // This program is distributed in the hope that it will be useful,\r
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 // GNU General Public License for more details.\r
16 //\r
17 // You should have received a copy of the GNU General Public License\r
18 // along with this program; if not, write to the Free Software\r
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
20 //\r
21 // Linking this library statically or dynamically with other modules is\r
22 // making a combined work based on this library.  Thus, the terms and\r
23 // conditions of the GNU General Public License cover the whole\r
24 // combination.\r
25 // \r
26 // As a special exception, the copyright holders of this library give you\r
27 // permission to link this library with independent modules to produce an\r
28 // executable, regardless of the license terms of these independent\r
29 // modules, and to copy and distribute the resulting executable under\r
30 // terms of your choice, provided that you also meet, for each linked\r
31 // independent module, the terms and conditions of the license of that\r
32 // module.  An independent module is a module which is not derived from\r
33 // or based on this library.  If you modify this library, you may extend\r
34 // this exception to your version of the library, but you are not\r
35 // obligated to do so.  If you do not wish to do so, delete this\r
36 // exception statement from your version.\r
37 \r
38 using System;\r
39 \r
40 namespace ICSharpCode.SharpZipLib.Checksums \r
41 {\r
42         \r
43         /// <summary>\r
44         /// Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:\r
45         /// 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.\r
46         ///\r
47         /// Polynomials over GF(2) are represented in binary, one bit per coefficient,\r
48         /// with the lowest powers in the most significant bit.  Then adding polynomials\r
49         /// is just exclusive-or, and multiplying a polynomial by x is a right shift by\r
50         /// one.  If we call the above polynomial p, and represent a byte as the\r
51         /// polynomial q, also with the lowest power in the most significant bit (so the\r
52         /// byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,\r
53         /// where a mod b means the remainder after dividing a by b.\r
54         ///\r
55         /// This calculation is done using the shift-register method of multiplying and\r
56         /// taking the remainder.  The register is initialized to zero, and for each\r
57         /// incoming bit, x^32 is added mod p to the register if the bit is a one (where\r
58         /// x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by\r
59         /// x (which is shifting right by one and adding x^32 mod p if the bit shifted\r
60         /// out is a one).  We start with the highest power (least significant bit) of\r
61         /// q and repeat for all eight bits of q.\r
62         ///\r
63         /// The table is simply the CRC of all possible eight bit values.  This is all\r
64         /// the information needed to generate CRC's on data a byte at a time for all\r
65         /// combinations of CRC register values and incoming bytes.\r
66         /// </summary>\r
67         public sealed class Crc32 : IChecksum\r
68         {\r
69                 readonly static uint CrcSeed = 0xFFFFFFFF;\r
70                 \r
71                 readonly static uint[] CrcTable = new uint[] {\r
72                         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,\r
73                         0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,\r
74                         0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07,\r
75                         0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,\r
76                         0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856,\r
77                         0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,\r
78                         0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,\r
79                         0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,\r
80                         0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,\r
81                         0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,\r
82                         0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599,\r
83                         0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,\r
84                         0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190,\r
85                         0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,\r
86                         0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E,\r
87                         0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,\r
88                         0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,\r
89                         0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,\r
90                         0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,\r
91                         0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,\r
92                         0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,\r
93                         0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,\r
94                         0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010,\r
95                         0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,\r
96                         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17,\r
97                         0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,\r
98                         0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,\r
99                         0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,\r
100                         0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344,\r
101                         0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,\r
102                         0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A,\r
103                         0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,\r
104                         0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1,\r
105                         0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,\r
106                         0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,\r
107                         0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,\r
108                         0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE,\r
109                         0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,\r
110                         0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C,\r
111                         0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,\r
112                         0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,\r
113                         0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,\r
114                         0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1,\r
115                         0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,\r
116                         0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,\r
117                         0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,\r
118                         0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66,\r
119                         0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,\r
120                         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,\r
121                         0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,\r
122                         0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,\r
123                         0x2D02EF8D\r
124                 };\r
125                 \r
126                 internal static uint ComputeCrc32(uint oldCrc, byte bval)\r
127                 {\r
128                         return (uint)(Crc32.CrcTable[(oldCrc ^ bval) & 0xFF] ^ (oldCrc >> 8));\r
129                 }\r
130                 \r
131                 /// <summary>\r
132                 /// The crc data checksum so far.\r
133                 /// </summary>\r
134                 uint crc = 0;\r
135                 \r
136                 /// <summary>\r
137                 /// Returns the CRC32 data checksum computed so far.\r
138                 /// </summary>\r
139                 public long Value {\r
140                         get {\r
141                                 return (long)crc;\r
142                         }\r
143                         set {\r
144                                 crc = (uint)value;\r
145                         }\r
146                 }\r
147                 \r
148                 /// <summary>\r
149                 /// Resets the CRC32 data checksum as if no update was ever called.\r
150                 /// </summary>\r
151                 public void Reset() \r
152                 { \r
153                         crc = 0; \r
154                 }\r
155                 \r
156                 /// <summary>\r
157                 /// Updates the checksum with the int bval.\r
158                 /// </summary>\r
159                 /// <param name = "bval">\r
160                 /// the byte is taken as the lower 8 bits of bval\r
161                 /// </param>\r
162                 public void Update(int bval)\r
163                 {\r
164                         crc ^= CrcSeed;\r
165                         crc  = CrcTable[(crc ^ bval) & 0xFF] ^ (crc >> 8);\r
166                         crc ^= CrcSeed;\r
167                 }\r
168                 \r
169                 /// <summary>\r
170                 /// Updates the checksum with the bytes taken from the array.\r
171                 /// </summary>\r
172                 /// <param name="buffer">\r
173                 /// buffer an array of bytes\r
174                 /// </param>\r
175                 public void Update(byte[] buffer)\r
176                 {\r
177                         Update(buffer, 0, buffer.Length);\r
178                 }\r
179                 \r
180                 /// <summary>\r
181                 /// Adds the byte array to the data checksum.\r
182                 /// </summary>\r
183                 /// <param name = "buf">\r
184                 /// the buffer which contains the data\r
185                 /// </param>\r
186                 /// <param name = "off">\r
187                 /// the offset in the buffer where the data starts\r
188                 /// </param>\r
189                 /// <param name = "len">\r
190                 /// the length of the data\r
191                 /// </param>\r
192                 public void Update(byte[] buf, int off, int len)\r
193                 {\r
194                         if (buf == null) {\r
195                                 throw new ArgumentNullException("buf");\r
196                         }\r
197                         \r
198                         if (off < 0 || len < 0 || off + len > buf.Length) {\r
199                                 throw new ArgumentOutOfRangeException();\r
200                         }\r
201                         \r
202                         crc ^= CrcSeed;\r
203                         \r
204                         while (--len >= 0) {\r
205                                 crc = CrcTable[(crc ^ buf[off++]) & 0xFF] ^ (crc >> 8);\r
206                         }\r
207                         \r
208                         crc ^= CrcSeed;\r
209                 }\r
210         }\r
211 }\r