XRootD
XrdOucCRC.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O u c C R C 3 2 . c c */
4 /* */
5 /* Produced by Andrew Hanushevsky for Stanford University under contract */
6 /* DE-AC02-76-SFO0515 with the Department of Energy */
7 /* */
8 /* This file is part of the XRootD software suite. */
9 /* */
10 /* XRootD is free software: you can redistribute it and/or modify it under */
11 /* the terms of the GNU Lesser General Public License as published by the */
12 /* Free Software Foundation, either version 3 of the License, or (at your */
13 /* option) any later version. */
14 /* */
15 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
16 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
17 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
18 /* License for more details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General Public License */
21 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
22 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
23 /* */
24 /* The copyright holder's institutional names and contributor's names may not */
25 /* be used to endorse or promote products derived from this software without */
26 /* specific prior written permission of the institution or contributor. */
27 /******************************************************************************/
28 
29 /*
30  C++ implementation of CRC-32 checksums. Code is based
31  upon and utilizes algorithm published by Ross Williams
32  as initially implemented by Eric Durbin.
33 
34  This file contains:
35  CRC lookup table
36  function CalcCRC32 for calculating CRC-32 checksum
37 
38  Provided by:
39  Eric Durbin
40  Kentucky Cancer Registry
41  University of Kentucky
42  October 14, 1998
43 
44  Status:
45  Public Domain
46 */
47 
48 #include "XrdOuc/XrdOucCRC.hh"
49 #include "XrdOuc/XrdOucCRC32C.hh"
50 
51 /*****************************************************************/
52 /* */
53 /* CRC LOOKUP TABLE */
54 /* ================ */
55 /* The following CRC lookup table was generated automagically */
56 /* by the Rocksoft^tm Model CRC Algorithm Table Generation */
57 /* Program V1.0 using the following model parameters: */
58 /* */
59 /* Width : 4 bytes. */
60 /* Poly : 0x04C11DB7L */
61 /* Reverse : TRUE. */
62 /* */
63 /* For more information on the Rocksoft^tm Model CRC Algorithm, */
64 /* see the document titled "A Painless Guide to CRC Error */
65 /* Detection Algorithms" by Ross Williams */
66 /* (ross@guest.adelaide.edu.au.). This document is likely to be */
67 /* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */
68 /* */
69 /*****************************************************************/
70 
71 unsigned int XrdOucCRC::crctable[256] =
72 {
73  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
74  0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
75  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
76  0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
77  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
78  0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
79  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
80  0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
81  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
82  0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
83  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
84  0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
85  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
86  0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
87  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
88  0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
89  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
90  0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
91  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
92  0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
93  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
94  0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
95  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
96  0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
97  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
98  0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
99  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
100  0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
101  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
102  0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
103  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
104  0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
105  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
106  0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
107  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
108  0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
109  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
110  0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
111  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
112  0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
113  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
114  0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
115  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
116  0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
117  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
118  0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
119  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
120  0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
121  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
122  0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
123  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
124  0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
125  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
126  0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
127  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
128  0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
129  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
130  0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
131  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
132  0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
133  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
134  0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
135  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
136  0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
137 };
138 
139 /*****************************************************************/
140 /* End of CRC Lookup Table */
141 /*****************************************************************/
142 
143 /******************************************************************************/
144 /* C R C 3 2 */
145 /******************************************************************************/
146 
147 /* Calculate CRC-32 Checksum for NAACCR Record,
148  skipping area of record containing checksum field.
149 
150  Uses reflected table driven method documented by Ross Williams.
151 
152  PARAMETERS:
153  unsigned char *p Record Buffer
154  unsigned long reclen Record Length
155 
156  RETURNS:
157  checksum value
158 
159  Author:
160  Eric Durbin 1998-10-14
161  Simplified by Andrew Hanushevsky 2007-07-20
162 
163  Status:
164  Public Domain
165 
166  Changes:
167  Compute CRC for complete buffer
168  Use unsigned int instead of long to insure 32 bit values.
169  Make this a C++ class.
170 */
171 uint32_t XrdOucCRC::CRC32(const unsigned char *p, int reclen)
172 {
173  const unsigned int CRC32_XINIT = 0xffffffff;
174  const unsigned int CRC32_XOROT = 0xffffffff;
175  unsigned int crc = CRC32_XINIT;
176 
177 // Process each byte
178 //
179  while(reclen-- > 0) crc = crctable[(crc ^ *p++) & 0xff] ^ (crc >> 8);
180 
181 // Return XOR out value
182 //
183  return crc ^ CRC32_XOROT;
184 }
185 
186 /******************************************************************************/
187 /* C R C 3 2 C */
188 /******************************************************************************/
189 
190 uint32_t XrdOucCRC::Calc32C(const void* data, size_t count, uint32_t prevcs)
191 {
192 
193 // Return the checksum
194 //
195  return crc32c(prevcs, data, count);
196 }
197 
198 /******************************************************************************/
199 
200 void XrdOucCRC::Calc32C(const void* data, size_t count, uint32_t* csval)
201 {
202  int i, numpages = count/XrdSys::PageSize;
203  const uint8_t* dataP = (const uint8_t*)data;
204 
205 // Calculate the CRC32C for each page
206 //
207  for (i = 0; i < numpages; i++)
208  {csval[i] = crc32c(0, dataP, XrdSys::PageSize);
209  count -= XrdSys::PageSize;
210  dataP += XrdSys::PageSize;
211  }
212 
213 // if there is anything left, calculate that as well
214 //
215  if (count > 0) csval[i] = crc32c(0, dataP, count);
216 }
217 
218 /******************************************************************************/
219 /* C o m b i n e 3 2 C */
220 /******************************************************************************/
221 
222 uint32_t XrdOucCRC::Combine32C(uint32_t Cksum1, uint32_t Cksum2, int DLen)
223 {
224  return crc32c_combine(Cksum1, Cksum2, (size_t)DLen);
225 }
226 
227 /******************************************************************************/
228 /* V e r 3 2 C */
229 /******************************************************************************/
230 
231 bool XrdOucCRC::Ver32C(const void* data, size_t count,
232  const uint32_t csval, uint32_t* valcs)
233 {
234  uint32_t actualCS;
235 
236 // Verify the checksum
237 //
238  actualCS = crc32c(0, data, count);
239  if (valcs) *valcs = actualCS;
240  return csval == actualCS;
241 }
242 
243 /******************************************************************************/
244 
245 int XrdOucCRC::Ver32C(const void* data, size_t count,
246  const uint32_t* csval, uint32_t& valcs)
247 {
248  int i, numpages = count/XrdSys::PageSize;
249  const uint8_t* dataP = (const uint8_t*)data;
250  uint32_t actualCS;
251 
252 // Calculate the CRC32C for each page and make sure it is the same.
253 //
254  for (i = 0; i < numpages; i++)
255  {
256  actualCS = crc32c(0, dataP, XrdSys::PageSize);
257  if (csval[i] != actualCS)
258  {valcs = actualCS;
259  return i;
260  }
261  count -= XrdSys::PageSize;
262  dataP += XrdSys::PageSize;
263  }
264 
265 // if there is anything left, verify that as well
266 //
267  if (count > 0)
268  {
269  actualCS = crc32c(0, dataP, count);
270  if (csval[i] != actualCS)
271  {valcs = actualCS;
272  return i;
273  }
274  }
275 
276 // Everything matched.
277 //
278  return -1;
279 }
280 
281 /******************************************************************************/
282 
283 bool XrdOucCRC::Ver32C(const void* data, size_t count,
284  const uint32_t* csval, bool* valok)
285 {
286  int i, numpages = count/XrdSys::PageSize;
287  const uint8_t* dataP = (const uint8_t*)data;
288  uint32_t actualCS;
289  bool retval = true;
290 
291 // Calculate the CRC32C for each page and make sure it is the same.
292 //
293  for (i = 0; i < numpages; i++)
294  {
295  actualCS = crc32c(0, dataP, XrdSys::PageSize);
296  if (csval[i] == actualCS) valok[i] = true;
297  else valok[i] = retval = false;
298  count -= XrdSys::PageSize;
299  dataP += XrdSys::PageSize;
300  }
301 
302 // if there is anything left, verify that as well
303 //
304  if (count > 0)
305  {
306  actualCS = crc32c(0, dataP, count);
307  if (csval[i] == actualCS) valok[i] = true;
308  else valok[i] = retval = false;
309  }
310 
311 // All done.
312 //
313  return retval;
314 }
315 
316 /******************************************************************************/
317 
318 bool XrdOucCRC::Ver32C(const void* data, size_t count,
319  const uint32_t* csval, uint32_t* valcs)
320 {
321  int i, numpages = count/XrdSys::PageSize;
322  const uint8_t* dataP = (const uint8_t*)data;
323  bool retval = true;
324 
325 // Calculate the CRC32C for each page and make sure it is the same.
326 //
327  for (i = 0; i < numpages; i++)
328  {
329  valcs[i] = crc32c(0, dataP, XrdSys::PageSize);
330  if (csval[i] != valcs[i]) retval = false;
331  count -= XrdSys::PageSize;
332  dataP += XrdSys::PageSize;
333  }
334 
335 // if there is anything left, verify that as well
336 //
337  if (count > 0)
338  {
339  valcs[i] = crc32c(0, dataP, count);
340  if (csval[i] != valcs[i]) retval = false;
341  }
342 
343 // All done.
344 //
345  return retval;
346 }
uint32_t crc32c(uint32_t crc, void const *buf, size_t len)
uint32_t crc32c_combine(uint32_t crcA, uint32_t crcB, size_t lengthB)
merge two CRC32 such that result = crc32(dataB, lengthB, crc32(dataA, lengthA))
static uint32_t CRC32(const unsigned char *data, int count)
Definition: XrdOucCRC.cc:171
static uint32_t Combine32C(uint32_t Cksum1, uint32_t Cksum2, int DLen)
Definition: XrdOucCRC.cc:222
static uint32_t Calc32C(const void *data, size_t count, uint32_t prevcs=0)
Definition: XrdOucCRC.cc:190
static bool Ver32C(const void *data, size_t count, const uint32_t csval, uint32_t *csbad=0)
Definition: XrdOucCRC.cc:231
static const int PageSize