www.digitalmars.com         C & C++   DMDScript  

D - CRC32 module not working?

reply soulshock <elite programmer.net> writes:
Why is it that

crctest.d:

uint crc32;

int main(char args[][]) {
     uint crc32;

     File f = new File(args[1]);
     crc32 = f.toHash;
     printf("crc: %u\n", crc32);

     return 0;
}

produces a different output than (C code compiled with GCC):

/* calc_crc32.c, v2.0
  * By jehsom jehsom.com */

#include <stdio.h>
#include <stdlib.h>

/* CRC lookup table */
static unsigned long crcs[256]={ 
0x00000000,0x77073096,0xEE0E612C,0x990951BA,
0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,
0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,
0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,
0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,
0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,
0xA50AB56B,0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,
0xDCD60DCF,0xABD13D59,0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,
0x56B3C423,0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,
0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,
0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,
0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,
0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,
0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,
0xFBD44C65,0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,
0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,
0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,
0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,
0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,
0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,
0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,
0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,
0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,
0x17B7BE43,0x60B08ED5,0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,
0xA6BC5767,0x3FB506DD,0x48B2364B,0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,
0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,
0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,
0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,
0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,
0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,
0x0BDBDF21,0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,
0x6FB077E1,0x18B74777,0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,
0xF862AE69,0x616BFFD3,0x166CCF45,0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,
0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,
0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,
0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,
0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D};

/* Calculates the 32-bit checksum of fname, and stores the result
  * in crc. Returns 0 on success, nonzero on error.
  */
int calc_crc32( const char *fname, unsigned long *crc ) {
     FILE *in;           /* input file */
     unsigned char buf[BUFSIZ]; /* pointer to the input buffer */
     size_t i, j;        /* buffer positions*/
     int k;              /* generic integer */
     unsigned long tmpcrc=0xFFFFFFFF;

     /* open file */
     if((in = fopen(fname, "rb")) == NULL) return -1;

     /* loop through the file and calculate CRC */
     while( (i=fread(buf, 1, BUFSIZ, in)) != 0 ){
         for(j=0; j<i; j++){
             k=(tmpcrc ^ buf[j]) & 0x000000FFL;
             tmpcrc=((tmpcrc >> 8) & 0x00FFFFFFL) ^ crcs[k];
         }
     }
     fclose(in);
     *crc=~tmpcrc; /* postconditioning */
     return 0;
}


int main( int argc, char *argv[] ) {
     unsigned long crc;

     if( argc < 2 ) {
         fprintf( stderr, "Usage: %s filename\n"
                  "  Calculates the 32-bit CRC of the given file.\n",
                  argv[0] );
         return EXIT_FAILURE;
     }

     if( calc_crc32(argv[1], &crc) != 0 ) {
         fprintf( stderr, "Error reading file %s.\n", argv[1] );
         return EXIT_FAILURE;
     }

     printf("CRC: %lu\n", crc);
     return EXIT_SUCCESS;
}
Apr 24 2004
next sibling parent reply =?ISO-8859-1?Q?Sigbj=F8rn_Lund_Olsen?= <sigbjorn lundolsen.net> writes:
soulshock wrote:

 Why is it that

*snip*
 produces a different output than (C code compiled with GCC):

A quick glance led me to believe that the two looks pretty much the same semantically, even though they obviously can't be. At any rate I'm going to cook myself dinner. It all boils down to food in the end. Here's a pretty good resource when it comes to CRC algorithms (there are many of them, just to make sure IT professionals are needed for years to come). http://www.repairfaq.org/filipg/LINK/F_crc_v3.html You should consider looking up the 'Adler32' hasing algorithm which is in zlib, it's pretty much equivalent with CRC's with good polys, when the sequence being hashed is over 128 bytes (iirc) and much faster. Cheers, Sigbjørn Lund Olsen
Apr 24 2004
parent soulshock <elite programmer.net> writes:
 Why is it that

*snip*
 produces a different output than (C code compiled with GCC):

A quick glance led me to believe that the two looks pretty much the same semantically, even though they obviously can't be. At any rate I'm going to cook myself dinner. It all boils down to food in the end. Here's a pretty good resource when it comes to CRC algorithms (there are many of them, just to make sure IT professionals are needed for years to come). http://www.repairfaq.org/filipg/LINK/F_crc_v3.html You should consider looking up the 'Adler32' hasing algorithm which is in zlib, it's pretty much equivalent with CRC's with good polys, when the sequence being hashed is over 128 bytes (iirc) and much faster.

Therein lies the problem. I need to implement it in a system utilizing the 32bit CRC, so using another check algorithm is not an option. Anyway the same code produces different results, is there some problem with the D compiler or perhaps the long integer being 32bit in C and normal integers being 32 bit in D is causing something of a problem.
Apr 24 2004
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
Because f.toHash() does not do a crc32 of a file, it does a hash of the f
object. To calculate a crc32, use std.zlib.crc32.
Apr 24 2004
parent =?ISO-8859-1?Q?Sigbj=F8rn_Lund_Olsen?= <sigbjorn lundolsen.net> writes:
Walter wrote:
 Because f.toHash() does not do a crc32 of a file, it does a hash of the f
 object. To calculate a crc32, use std.zlib.crc32.

There's also a std.crc32 module, which is used in std.stream again. I should have looked at his code instead of automatically looked at crc32.d. :-/ Cheers, Sigbjørn Lund Olsen
Apr 25 2004