Any bit-twiddling, CRC-generation experts out there? I'm trying to implement an Xmodem CRC receive function. I have code from here in C# but it doesn't implement CRC on receiving, only on sending. I also have code from here in C that does implement CRC on receiving. The C# code looks like it was based on the C code.
I've got my code doing the CRC checking in what *I think* is the same way the C code is doing it, but when I connect to one of my company's remote devices and try to retrieve a file, the CRC values never match. I can retrieve a file fine using Xmodem CRC in Tera Term Pro when connecting to the same device (I'm doing this over sockets, not serial, if that matters).
The CRC-16 lookup table used by both the C and C# code are the same. Are these C/C# code blocks equivalent? And if they *are* equivalent, can anyone tell what I'm doing wrong that makes the crc comparison fail?? ('buf' contains the block of data received that needs to be checked; 'sz' is either 1024 or 128)
C#: private bool check(bool isCrc, byte[] buf, int index, int sz) { // 'index' has a value of '3' passed in if (isCrc) { ushort crc = CRC16.CRC16_ccitt(buf, index, sz); ushort tcrc = (ushort)((buf[sz + index] << 8) + buf[sz + index + 1]); if (crc == tcrc) return true; } return false; }
C: static int check(int crc, const unsigned char *buf, int sz) { if (crc) { unsigned short crc = crc16_ccitt(buf, sz); unsigned short tcrc = (buf[sz]<<8)+buf[sz+1]; if (crc == tcrc) return 1;
} return 0; }
------------------------------And are these blocks equivalent?
C#: static public ushort CRC16_ccitt(byte[] buf, int index, int len) { int counter; ushort crc = 0; for( counter = 0; counter < len; counter++) crc = (ushort)((crc << 8) ^ crc16tab[((crc >> 8) ^ buf[index + counter]) & 0x00FF]); return crc; }
C: unsigned short crc16_ccitt(const void *buf, int len) { register int counter; register unsigned short crc = 0; for( counter = 0; counter < len; counter++) crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF]; return crc; }