// // NSData+CRC.m // CommonLibrary // // Created by Ken on 3/25/14. // Copyright (c) 2014 Alexi. All rights reserved. // #import "NSData+CRC.h" @implementation NSData (CRC) - (uint8_t)crc8 { uint8_t i; uint8_t crc=0; uint8_t in_len = [self length]; uint8_t* in_ptr = (uint8_t *)[self bytes]; while(in_len--!=0) { for(i=0x80; i!=0; i/=2) { if((crc&0x80)!=0) {crc*=2; crc^=0xE5;} //余式CRC 乘以2 再求CRC else crc*=2; if((*in_ptr&i)!=0) crc^=0xE5; //再加上本位的CRC } in_ptr++; } return(crc); } //*********************************************************************************************************** // Function : generateCRC32Table // // Description : Generates a lookup table for CRC calculations using a supplied polynomial. // // Declaration : void generateCRC32Table(uint32_t *pTable, uint32_t poly); // // Parameters : pTable // A pointer to pre-allocated memory to store the lookup table. // // poly // The polynomial to use in calculating the CRC table values. // // Return Value : None. //*********************************************************************************************************** void generateCRC32Table(uint32_t *pTable, uint32_t poly) { for (uint32_t i = 0; i <= 255; i++) { uint32_t crc = i; for (uint32_t j = 8; j > 0; j--) { if ((crc & 1) == 1) crc = (crc >> 1) ^ poly; else crc >>= 1; } pTable[i] = crc; } } //*********************************************************************************************************** // Method : crc32 // // Description : Calculates the CRC32 of a data object using the default seed and polynomial. // // Declaration : -(uint32_t)crc32; // // Parameters : None. // // Return Value : The CRC32 value. //*********************************************************************************************************** - (uint32_t)crc32 { return [self crc32WithSeed:DEFAULT_SEED usingPolynomial:DEFAULT_POLYNOMIAL]; } //*********************************************************************************************************** // Method : crc32WithSeed: // // Description : Calculates the CRC32 of a data object using a supplied seed and default polynomial. // // Declaration : -(uint32_t)crc32WithSeed:(uint32_t)seed; // // Parameters : seed // The initial CRC value. // // Return Value : The CRC32 value. //*********************************************************************************************************** - (uint32_t)crc32WithSeed:(uint32_t)seed { return [self crc32WithSeed:seed usingPolynomial:DEFAULT_POLYNOMIAL]; } //*********************************************************************************************************** // Method : crc32UsingPolynomial: // // Description : Calculates the CRC32 of a data object using a supplied polynomial and default seed. // // Declaration : -(uint32_t)crc32UsingPolynomial:(uint32_t)poly; // // Parameters : poly // The polynomial to use in calculating the CRC. // // Return Value : The CRC32 value. //*********************************************************************************************************** - (uint32_t)crc32UsingPolynomial:(uint32_t)poly { return [self crc32WithSeed:DEFAULT_SEED usingPolynomial:poly]; } //*********************************************************************************************************** // Method : crc32WithSeed:usingPolynomial: // // Description : Calculates the CRC32 of a data object using supplied polynomial and seed values. // // Declaration : -(uint32_t)crc32WithSeed:(uint32_t)seed usingPolynomial:(uint32_t)poly; // // Parameters : seed // The initial CRC value. // // : poly // The polynomial to use in calculating the CRC. // // Return Value : The CRC32 value. //*********************************************************************************************************** - (uint32_t)crc32WithSeed:(uint32_t)seed usingPolynomial:(uint32_t)poly { uint32_t *pTable = (uint32_t *)malloc(sizeof(uint32_t) * 256); generateCRC32Table(pTable, poly); uint32_t crc = seed; uint8_t *pBytes = (uint8_t *)[self bytes]; NSUInteger length = [self length]; while (length--) { crc = (crc>>8) ^ pTable[(crc & 0xFF) ^ *pBytes++]; } free(pTable); return crc ^ 0xFFFFFFFFL; } @end