home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / crcksrc.zip / crc24.cpp next >
Text File  |  1995-02-15  |  6KB  |  192 lines

  1. /*
  2. $Header: e:/work2/x/jacquard/src/control/RCS/crc24.cpp 1.2 93/06/23 05:09:50 m3m rel $
  3. **
  4. **
  5. ** Copyright M CUBED 1993, ALL RIGHTS DESERVED
  6. ** author   : Michael McDaniel
  7. **
  8. ** This work is derived in part from public domain code, and is contributed
  9. ** back to the public domain
  10. **
  11. ** ===>>> please keep my credits when you add your own <<<===
  12. **
  13. **
  14. ** purpose  : calculate 24bit cyclic redundancy check
  15. **
  16. ** see also : crc24.h, pgp21, armor.c
  17. **
  18. ** reference: 1) "C Programmer's Guide to Serial Communications",
  19. **               by Joe Campbell
  20. **               These CRC functions are derived from code in chapter 19
  21. **               Generalized to any CRC width by Philip Zimmermann; 24 bit
  22. **               width used here.
  23. **
  24. ** suggested enhancement: read more than one character at a time. This was
  25. ** originally linked into a commercial product strictly for an integrity
  26. ** check of the executable so as seldom as it was run, reading one character
  27. ** at a time was not an issue. Now that this is harnessed with crck.cpp and
  28. ** used to check multiple files, fixing the one-char-etc. bottleneck would
  29. ** probably be worth it.
  30. */
  31.  
  32. # define __CRC24_CPP_
  33.  
  34. static char rcsid[] = "$Header: e:/work2/x/jacquard/src/control/RCS/crc24.cpp 1.2 93/06/23 05:09:50 m3m rel $";
  35.  
  36.  
  37. # include <io.h>
  38. # include <fstream.h>
  39.  
  40. # include "crc24.h"
  41.  
  42.  
  43. const CRCBITS           = 24;
  44. const crcword CRCINIT   = 0xB704CEUL;        // Init value for CRC accumulator
  45. const crcword PRZCRC    = 0x864cfbUL;        // PRZ's 24-bit CRC generator polynomial
  46. const crcword CRCHIBIT  = 1UL << (CRCBITS-1UL);      // 0x8000 if CRCBITS is 16
  47. const crcword CRCSHIFTS = CRCBITS - 8 ;
  48.  
  49.  
  50. typedef unsigned char byte;
  51.  
  52. crcword crctable[256];                             // Table for speeding up CRC's
  53.  
  54.  
  55. inline crcword maskcrc(crcword crc)
  56. {
  57.    return (crc & 0xffffffL);                  // if CRCBITS is 24
  58. }
  59.  
  60.  
  61.  
  62.  
  63. crc24::crc24( char * file_name )
  64. {                                                     // member vars
  65.    accum    = CRCINIT;
  66.    pvalid   = 1;
  67.                                                       // local vars
  68.    int data = 0;
  69.    fstream executable;
  70.  
  71.    if( access(file_name, 04) == 0 )
  72.    {
  73.       executable.open( file_name, ios::in | ios::binary );
  74.    }
  75.    else
  76.       pvalid = 0;
  77.  
  78.    if( pvalid && !executable.bad() )
  79.    {
  80.       mk_crctbl(PRZCRC);
  81.       while( data != EOF )
  82.       {
  83.          data   = executable.get();
  84.          accum  = crcupdate( (unsigned char)data, accum);
  85.       }
  86.    }
  87.  
  88.    executable.close();
  89.  
  90. }; // end crc24
  91.  
  92.  
  93.  
  94.  
  95. crc24::~crc24()
  96. {
  97.    accum = 0;
  98.  
  99. }; // end ~crc24()
  100.  
  101.  
  102.  
  103.  
  104. unsigned long crc24::value()
  105. {
  106.    return accum;
  107. };
  108.  
  109.  
  110. // m3m; the following are verbatim out of armor.c in pgp21/src
  111. // crc24:: added
  112.  
  113.  
  114. /*      Notes on making a good 24-bit CRC--
  115.         The primitive irreducible polynomial of degree 23 over GF(2),
  116.         040435651 (octal), comes from Appendix C of "Error Correcting Codes,
  117.         2nd edition" by Peterson and Weldon, page 490.  This polynomial was
  118.         chosen for its uniform density of ones and zeros, which has better
  119.         error detection properties than polynomials with a minimal number of
  120.         nonzero terms.  Multiplying this primitive degree-23 polynomial by
  121.         the polynomial x+1 yields the additional property of detecting any
  122.         odd number of bits in error, which means it adds parity.  This
  123.         approach was recommended by Neal Glover.
  124.  
  125.         To multiply the polynomial 040435651 by x+1, shift it left 1 bit and
  126.         bitwise add (xor) the unshifted version back in.  Dropping the unused
  127.         upper bit (bit 24) produces a CRC-24 generator bitmask of 041446373
  128.         octal, or 0x864cfb hex.
  129.  
  130.         You can detect spurious leading zeros or framing errors in the
  131.         message by initializing the CRC accumulator to some agreed-upon
  132.         nonzero "random-like" value, but this is a bit nonstandard.
  133. */
  134.  
  135.  
  136.  
  137.  
  138. crcword crc24::crchware(byte ch, crcword poly, crcword accum)
  139. //
  140. // crchware simulates CRC hardware circuit.  Generates true CRC
  141. // directly, without requiring extra NULL bytes to be appended
  142. // to the message.
  143. // Returns new updated CRC accumulator.
  144. //
  145. {       int i;
  146.         crcword data;
  147.         data = ch;
  148.         data <<= CRCSHIFTS;     /* shift data to line up with MSB of accum */
  149.         i = 8;          /* counts 8 bits of data */
  150.         do
  151.         {       /* if MSB of (data XOR accum) is TRUE, shift and subtract poly */
  152.                 if ((data ^ accum) & CRCHIBIT)
  153.                         accum = (accum<<1) ^ poly;
  154.                 else
  155.                         accum <<= 1;
  156.                 data <<= 1;
  157.         } while (--i);  /* counts 8 bits of data */
  158.         return (maskcrc(accum));
  159. }       /* crchware */
  160.  
  161.  
  162. void crc24::mk_crctbl(crcword poly)
  163. //
  164. // mk_crctbl derives a CRC lookup table from the CRC polynomial.
  165. // The table is used later by crcupdate function given below.
  166. // mk_crctbl only needs to be called once at the dawn of time.
  167. //
  168. {       int i;
  169.         for (i=0; i<256; i++)
  170.                 crctable[i] = crchware((byte) i, poly, 0);
  171. }       /* mk_crctbl */
  172.  
  173.  
  174. crcword crc24::crcupdate(byte data, register crcword accum)
  175. //
  176. // crcupdate calculates a CRC using the fast table-lookup method.
  177. // Returns new updated CRC accumulator.
  178. //
  179. {       byte combined_value;
  180.  
  181.         /* XOR the MSByte of the accum with the data byte */
  182.         combined_value = (accum >> CRCSHIFTS) ^ data;
  183.         accum = (accum << 8) ^ crctable[combined_value];
  184.         return (maskcrc(accum));
  185. }       /* crcupdate */
  186.  
  187.  
  188.  
  189.  
  190. // end $Source: e:/work2/x/jacquard/src/control/RCS/crc24.cpp $
  191.  
  192.