crc.cc

Go to the documentation of this file.
00001 /*
00002  *  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
00003  *  code or tables extracted from it, as desired without restriction.
00004  *
00005  *  (modified for use in Exult)
00006  *
00007  *  First, the polynomial itself and its table of feedback terms.  The
00008  *  polynomial is
00009  *  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+X^0
00010  *
00011  *  Note that we take it "backwards" and put the highest-order term in
00012  *  the lowest-order bit.  The X^32 term is "implied"; the LSB is the
00013  *  X^31 term, etc.  The X^0 term (usually shown as "+1") results in
00014  *  the MSB being 1
00015  *
00016  *  Note that the usual hardware shift register implementation, which
00017  *  is what we're using (we're merely optimizing it by doing eight-bit
00018  *  chunks at a time) shifts bits into the lowest-order term.  In our
00019  *  implementation, that means shifting towards the right.  Why do we
00020  *  do it this way?  Because the calculated CRC must be transmitted in
00021  *  order from highest-order term to lowest-order term.  UARTs transmit
00022  *  characters in order from LSB to MSB.  By storing the CRC this way
00023  *  we hand it to the UART in the order low-byte to high-byte; the UART
00024  *  sends each low-bit to hight-bit; and the result is transmission bit
00025  *  by bit from highest- to lowest-order term without requiring any bit
00026  *  shuffling on our part.  Reception works similarly
00027  *
00028  *  The feedback terms table consists of 256, 32-bit entries.  Notes
00029  *
00030  *      The table can be generated at runtime if desired; code to do so
00031  *      is shown later.  It might not be obvious, but the feedback
00032  *      terms simply represent the results of eight shift/xor opera
00033  *      tions for all combinations of data and CRC register values
00034  *
00035  *      The values must be right-shifted by eight bits by the "updcrc
00036  *      logic; the shift must be unsigned (bring in zeroes).  On some
00037  *      hardware you could probably optimize the shift in assembler by
00038  *      using byte-swap instructions
00039  *      polynomial $edb88320
00040  */
00041 
00042 #ifdef HAVE_CONFIG_H
00043 #  include <config.h>
00044 #endif
00045 
00046 #include "crc.h"
00047 #include "common_types.h"
00048 #include "utils.h"
00049 #include <fstream>
00050 
00051 static uint32 crc32_tab[] = {
00052   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
00053   0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
00054   0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
00055   0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
00056   0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
00057   0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
00058   0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
00059   0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
00060   0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
00061   0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
00062   0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
00063   0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
00064   0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
00065   0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
00066   0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
00067   0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
00068   0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
00069   0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
00070   0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
00071   0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
00072   0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
00073   0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
00074   0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
00075   0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
00076   0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
00077   0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
00078   0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
00079   0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
00080   0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
00081   0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
00082   0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
00083   0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
00084   0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
00085   0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
00086   0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
00087   0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
00088   0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
00089   0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
00090   0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
00091   0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
00092   0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
00093   0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
00094   0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
00095   0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
00096   0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
00097   0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
00098   0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
00099   0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
00100   0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
00101   0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
00102   0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
00103   0x2d02ef8dL
00104 };
00105 
00106 /*
00107 unsigned int ssh_crc32(const unsigned char *s, unsigned int len)
00108 {
00109   unsigned int i;
00110   unsigned int crc32val;
00111 
00112   crc32val = 0;
00113   for (i = 0;  i < len;  i ++) {
00114     crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
00115   }
00116   return crc32val;
00117 }
00118 */
00119 
00120 uint32 crc32(const char *filename)
00121 {
00122   std::ifstream crcfile(filename, std::ios::binary | std::ios::in);
00123 
00124   uint32 crc32val = 0;
00125   unsigned char c;
00126 
00127   crcfile.get(reinterpret_cast<char &>(c));
00128   while (crcfile.good()) {
00129     crc32val = crc32_tab[(crc32val ^ c) & 0xff] ^ (crc32val >> 8);
00130     crcfile.get(reinterpret_cast<char &>(c));
00131   }
00132 
00133   return crc32val;
00134 }
00135 
00136 uint32 crc32_syspath(const char *filename)
00137 {
00138   return crc32(get_system_path(filename).c_str());
00139 }

Generated on Mon Jul 9 14:42:45 2007 for ExultEngine by  doxygen 1.5.1