00001 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and 00002 // repair tool). See https://parchive.sourceforge.net for details of PAR 2.0. 00003 // 00004 // Copyright (c) 2003 Peter Brian Clements 00005 // 00006 // par2cmdline is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // par2cmdline is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 #ifndef __CRC_H__ 00021 #define __CRC_H__ 00022 00023 // These global functions are used to compute the CCITT CRC32 checksum of 00024 // blocks of data. 00025 00026 // The CRC for a block of data may be computed piecemeal be repeatedly 00027 // calling CRCUpdateChar, and CRCUpdateBlock. 00028 00029 // Given the CRC for a block of data in a buffer, CRCSlideChar may be used 00030 // to quickly compute the CRC for the block of data in the buffer that is the 00031 // same size but offset one character later in the buffer. 00032 00033 00034 // Construct the CRC32 lookup table from the specified polynomial 00035 void GenerateCRC32Table(u32 polynomial, u32 (&table)[256]); 00036 00037 // A CRC32 lookup table 00038 struct crc32table 00039 { 00040 crc32table(u32 polynomial) 00041 { 00042 GenerateCRC32Table(polynomial, table); 00043 } 00044 00045 u32 table[256]; 00046 }; 00047 00048 // The one and only CCITT CRC32 lookup table 00049 extern crc32table ccitttable; 00050 00051 // Update the CRC using one character 00052 inline u32 CRCUpdateChar(u32 crc, u8 ch) 00053 { 00054 return ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc ^ ch]; 00055 } 00056 00057 // Update the CRC using a block of characters in a buffer 00058 inline u32 CRCUpdateBlock(u32 crc, size_t length, const void *buffer) 00059 { 00060 const unsigned char *current = (const unsigned char *)buffer; 00061 00062 while (length-- > 0) 00063 { 00064 crc = ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc ^ (*current++)]; 00065 } 00066 00067 return crc; 00068 } 00069 00070 // Update the CRC using a block of 0s. 00071 inline u32 CRCUpdateBlock(u32 crc, size_t length) 00072 { 00073 while (length-- > 0) 00074 { 00075 crc = ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc]; 00076 } 00077 00078 return crc; 00079 } 00080 00081 // Construct a CRC32 lookup table for windowing 00082 void GenerateWindowTable(u64 window, u32 (&windowtable)[256]); 00083 // Construct the mask value to apply to the CRC when windowing 00084 u32 ComputeWindowMask(u64 window); 00085 00086 // Slide the CRC along a buffer by one character (removing the old and adding the new). 00087 // The new character is added using the main CCITT CRC32 table, and the old character 00088 // is removed using the windowtable. 00089 inline u32 CRCSlideChar(u32 crc, u8 chNew, u8 chOld, const u32 (&windowtable)[256]) 00090 { 00091 return ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc ^ chNew] ^ windowtable[chOld]; 00092 } 00093 00094 /* 00095 00096 char *buffer; 00097 u64 window; 00098 00099 //... 00100 00101 u32 windowtable[256]; 00102 GenerateWindowTable(window, windowtable); 00103 u32 windowmask = ComputeWindowMask(window); 00104 00105 u32 crc = ~0 ^ CRCUpdateBlock(~0, window, buffer); 00106 crc = windowmask ^ CRCSlideChar(windowmask ^ crc, buffer[window], buffer[0], windowtable); 00107 00108 assert(crc == ~0 ^ CRCUpdateBlock(~0, window, buffer+1)); 00109 00110 */ 00111 00112 00113 #endif // __CRC_H__