File:  [ELWIX - Embedded LightWeight unIX -] / libaitcrc / src / aitcrc.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Wed Jan 20 00:04:45 2010 UTC (14 years, 5 months ago) by misho
Branches: MAIN
CVS tags: crc1_2, HEAD, CRC1_1
version 1.1

    1: /*************************************************************************
    2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
    3: *  by Michael Pounov <misho@openbsd-bg.org>
    4: *
    5: * $Author: misho $
    6: * $Id: aitcrc.c,v 1.2 2010/01/20 00:04:45 misho Exp $
    7: *
    8: *************************************************************************/
    9: #include "global.h"
   10: 
   11: 
   12: static int crc_Errno;
   13: static char crc_Error[MAX_STR + 1];
   14: 
   15: // Adler module
   16: const u_long crc_modAdler = 0xFFF1L;
   17: 
   18: // All known library CRC types ...
   19: const crcPoly_t crc_Poly[] = {
   20: 	{ 1, (u_long) 0x1, "CRC-1-Parity" }, 
   21: 	{ 4, (u_long) 0x3, "CRC-4-ITU" }, 
   22: 	{ 5, (u_long) 0x15, "CRC-5-ITU" }, 
   23: 	{ 6, (u_long) 0x3, "CRC-6-ITU" }, 
   24: 	{ 7, (u_long) 0x9, "CRC-7-MMC" }, 
   25: 	{ 8, (u_long) 0x8D, "CRC-8-CCITT" }, 
   26: 	{ 10, (u_long) 0x233, "CRC-10" }, 
   27: 	{ 11, (u_long) 0x385, "CRC-11-FlexRay" }, 
   28: 	{ 12, (u_long) 0x80F, "CRC-12-Telco" }, 
   29: 	{ 15, (u_long) 0x4599, "CRC-15-CAN" }, 
   30: 	{ 16, (u_long) 0x8005, "CRC-16-IBM" }, 
   31: 	{ 24, (u_long) 0x864CFB, "CRC-24-Radix64" }, 
   32: 	{ 30, (u_long) 0x2030B9C7, "CRC-30-CDMA" }, 
   33: 	{ 32, (u_long) 0x04C11DB7, "CRC-32-802.3" }
   34: };
   35: 
   36: // ----------------------------------------------------------
   37: 
   38: //
   39: // Error maintenance functions ...
   40: //
   41: 
   42: // crc_GetErrno() Get error code of last operation
   43: inline int crc_GetErrno()
   44: {
   45: 	return crc_Errno;
   46: }
   47: 
   48: // crc_GetError() Get error text of last operation
   49: inline const char *crc_GetError()
   50: {
   51: 	return crc_Error;
   52: }
   53: 
   54: // crcSetErr() Set error to variables for internal use!!!
   55: inline void crcSetErr(int eno, char *estr, ...)
   56: {
   57: 	va_list lst;
   58: 
   59: 	crc_Errno = eno;
   60: 	memset(crc_Error, 0, MAX_STR + 1);
   61: 	va_start(lst, estr);
   62: 	vsnprintf(crc_Error, MAX_STR + 1, estr, lst);
   63: 	va_end(lst);
   64: }
   65: 
   66: // ----------------------------------------------------------
   67: 
   68: /*
   69:  * crcReflect() Reflect all bits of number 
   70:  * @crcNum = Number for reflection
   71:  * @crcBits = Number width bits 
   72:  * return: -1 error, !=-1 reflecting number
   73:  */
   74: inline u_long crcReflect(u_long crcNum, u_char crcBits)
   75: {
   76: 	register u_long i, j, rev;
   77: 
   78: 	for (i = (u_long) 1 << (crcBits - 1), j = 1, rev ^= rev; i; i >>= 1, j <<= 1)
   79: 		if (crcNum & i)
   80: 			rev |= j;
   81: 
   82: 	crc_Errno ^= crc_Errno;
   83: 	return rev;
   84: }
   85: 
   86: /*
   87:  * crcCalc() Generic CRC calculation function for many sub variants of CRC algorithms
   88:  * @psBuf = Data for calculation
   89:  * @bufLen = Length of data
   90:  * @crcBits = CRC algorithm bits (1, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 24, 30, 32)
   91:  * @RevOpts = Options for computation (REVOPTS_REVERTBYTE, REVOPTS_REVERTCRC)
   92:  * @initCRC = Initial CRC value
   93:  * @xorCRC = Last xor CRC value
   94:  * return: -1 error, !=-1 CRC checksum
   95:  */
   96: inline u_long crcCalc(u_char * __restrict psBuf, u_int bufLen, u_char crcBits, u_char RevOpts, u_long initCRC, u_long xorCRC)
   97: {
   98: 	const u_long bits = sizeof(long) * 8 - crcBits;
   99: 	u_long poly, crchibit, crc;
  100: 	register u_long i, j, b, ch;
  101: 
  102: 	if (!psBuf) {
  103: 		crc_Errno = 1;
  104: 		strlcpy(crc_Error, "crcCalc(): Invalid parameters!", MAX_STR + 1);
  105: 		return -1;
  106: 	}
  107: 
  108: 	switch (crcBits) {
  109: 		case 1:
  110: 			poly = crc_Poly[0].poly_num;
  111: 			break;
  112: 		case 4:
  113: 			poly = crc_Poly[1].poly_num;
  114: 			break;
  115: 		case 5:
  116: 			poly = crc_Poly[2].poly_num;
  117: 			break;
  118: 		case 6:
  119: 			poly = crc_Poly[3].poly_num;
  120: 			break;
  121: 		case 7:
  122: 			poly = crc_Poly[4].poly_num;
  123: 			break;
  124: 		case 8:
  125: 			poly = crc_Poly[5].poly_num;
  126: 			break;
  127: 		case 10:
  128: 			poly = crc_Poly[6].poly_num;
  129: 			break;
  130: 		case 11:
  131: 			poly = crc_Poly[7].poly_num;
  132: 			break;
  133: 		case 12:
  134: 			poly = crc_Poly[8].poly_num;
  135: 			break;
  136: 		case 15:
  137: 			poly = crc_Poly[9].poly_num;
  138: 			break;
  139: 		case 16:
  140: 			poly = crc_Poly[10].poly_num;
  141: 			break;
  142: 		case 24:
  143: 			poly = crc_Poly[11].poly_num;
  144: 			break;
  145: 		case 30:
  146: 			poly = crc_Poly[12].poly_num;
  147: 			break;
  148: 		case 32:
  149: 			poly = crc_Poly[13].poly_num;
  150: 			break;
  151: 		default:
  152: 			crc_Errno = 2;
  153: 			strlcpy(crc_Error, "crcCalc(): Unsupported CRC method!!!", MAX_STR + 1);
  154: 			return -1;
  155: 	}
  156: 	poly <<= bits;
  157: 
  158: 	crchibit = (u_long) 1 << (crcBits - 1);
  159: 	crchibit <<= bits;
  160: 	crc = initCRC << bits;
  161: 
  162: 	for (i = 0; i < bufLen; i++) {
  163: 		ch = (u_long) *psBuf++;
  164: 		if (RevOpts & REVOPTS_REVERTBYTE)
  165: 			ch = crcReflect(ch, 8);
  166: 
  167: 		for (j = 0x80; j; j >>= 1) {
  168: 			b = crc & crchibit;
  169: 			crc <<= 1;
  170: 
  171: 			if (ch & j)
  172: 				b ^= crchibit;
  173: 			if (b)
  174: 				crc ^= poly;
  175: 		}
  176: 	}
  177: 
  178: 	if (RevOpts & REVOPTS_REVERTCRC)
  179: 		crc = crcReflect(crc, sizeof(long) * 8);
  180: 	crc ^= xorCRC << bits;
  181: 	crc &= (((crchibit - 1) << 1) | 1);
  182: 	if (!(RevOpts & REVOPTS_REVERTCRC))
  183: 		crc >>= bits;
  184: 
  185: 	crc_Errno ^= crc_Errno;
  186: 	return crc;
  187: }
  188: 
  189: // ----------------------------------------------------------
  190: 
  191: /*
  192:  * crcIP() Checksum in IP communication
  193:  * @nBuf = Data for calculation
  194:  * @bufLen = Length of data
  195:  * return: -1 error, !=-1 Checksum
  196:  */
  197: inline u_short crcIP(u_short * __restrict nBuf, int bufLen)
  198: {
  199: 	register u_long sum;
  200: 
  201: 	if (!nBuf) {
  202: 		crc_Errno = 1;
  203: 		strlcpy(crc_Error, "crcIP(): Invalid parameters!", MAX_STR + 1);
  204: 		return -1;
  205: 	}
  206: 
  207: 	for (sum = 0; bufLen; bufLen--)
  208: 		sum += *nBuf++;
  209: 
  210: 	sum = (sum >> 16) + (sum & 0xFFFF);
  211: 	sum += sum >> 16;
  212: 
  213: 	crc_Errno ^= crc_Errno;
  214: 	return (u_short) ~sum;
  215: }
  216: 
  217: /*
  218:  * crcFletcher() Fletcher-16 Checksum computing
  219:  * @nBuf = Data for calculation
  220:  * @bufLen = Length of data
  221:  * return: -1 error, !=-1 Checksum
  222:  */
  223: inline u_long crcFletcher(u_short * __restrict nBuf, int bufLen)
  224: {
  225: 	register u_long s1, s2, clen;
  226: 
  227: 	if (!nBuf) {
  228: 		crc_Errno = 1;
  229: 		strlcpy(crc_Error, "crcFletcher(): Invalid parameters!", MAX_STR + 1);
  230: 		return -1;
  231: 	}
  232: 
  233: 	s1 = s2 = 0xFFFF;
  234: 	while (bufLen) {
  235: 		clen = bufLen > MAX_FLETCHER_DIGEST ? MAX_FLETCHER_DIGEST : bufLen;
  236: 		bufLen -= clen;
  237: 
  238: 		do {
  239: 			s1 += (u_long) *nBuf++;
  240: 			s2 += s1;
  241: 		} while (--clen);
  242: 
  243: 		s1 = (s1 >> 16) + (s1 & 0xFFFF);
  244: 		s2 = (s2 >> 16) + (s2 & 0xFFFF);
  245: 	}
  246: 
  247: 	crc_Errno ^= crc_Errno;
  248: 	return (s2 << 16) | s1;
  249: }
  250: 
  251: /*
  252:  * crcAdler() crcAdler-32 Checksum computing
  253:  * @psBuf = Data for calculation
  254:  * @bufLen = Length of data
  255:  * return: -1 error, !=-1 Checksum
  256:  */
  257: inline u_long crcAdler(u_char * __restrict psBuf, int bufLen)
  258: {
  259: 	register u_long s1, s2, clen;
  260: 
  261: 	if (!psBuf) {
  262: 		crc_Errno = 1;
  263: 		strlcpy(crc_Error, "crcAdler(): Invalid parameters!", MAX_STR + 1);
  264: 		return -1;
  265: 	}
  266: 
  267: 	s1 = 1L;
  268: 	s2 ^= s2;
  269: 	while (bufLen) {
  270: 		clen = bufLen > MAX_ADLER_DIGEST ? MAX_ADLER_DIGEST : bufLen;
  271: 		bufLen -= clen;
  272: 
  273: 		do {
  274: 			s1 += (u_long) *psBuf++;
  275: 			s2 += s1;
  276: 		} while (--clen);
  277: 
  278: 		s1 %= crc_modAdler;
  279: 		s2 %= crc_modAdler;
  280: 	}
  281: 
  282: 	crc_Errno ^= crc_Errno;
  283: 	return (s2 << 16) | s1;
  284: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>