NSData+CRC.m 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //
  2. // NSData+CRC.m
  3. // CommonLibrary
  4. //
  5. // Created by Ken on 3/25/14.
  6. // Copyright (c) 2014 Alexi. All rights reserved.
  7. //
  8. #import "NSData+CRC.h"
  9. @implementation NSData (CRC)
  10. - (uint8_t)crc8
  11. {
  12. uint8_t i;
  13. uint8_t crc=0;
  14. uint8_t in_len = [self length];
  15. uint8_t* in_ptr = (uint8_t *)[self bytes];
  16. while(in_len--!=0)
  17. {
  18. for(i=0x80; i!=0; i/=2)
  19. {
  20. if((crc&0x80)!=0) {crc*=2; crc^=0xE5;} //余式CRC 乘以2 再求CRC
  21. else crc*=2;
  22. if((*in_ptr&i)!=0) crc^=0xE5; //再加上本位的CRC
  23. }
  24. in_ptr++;
  25. }
  26. return(crc);
  27. }
  28. //***********************************************************************************************************
  29. // Function : generateCRC32Table
  30. //
  31. // Description : Generates a lookup table for CRC calculations using a supplied polynomial.
  32. //
  33. // Declaration : void generateCRC32Table(uint32_t *pTable, uint32_t poly);
  34. //
  35. // Parameters : pTable
  36. // A pointer to pre-allocated memory to store the lookup table.
  37. //
  38. // poly
  39. // The polynomial to use in calculating the CRC table values.
  40. //
  41. // Return Value : None.
  42. //***********************************************************************************************************
  43. void generateCRC32Table(uint32_t *pTable, uint32_t poly)
  44. {
  45. for (uint32_t i = 0; i <= 255; i++)
  46. {
  47. uint32_t crc = i;
  48. for (uint32_t j = 8; j > 0; j--)
  49. {
  50. if ((crc & 1) == 1)
  51. crc = (crc >> 1) ^ poly;
  52. else
  53. crc >>= 1;
  54. }
  55. pTable[i] = crc;
  56. }
  57. }
  58. //***********************************************************************************************************
  59. // Method : crc32
  60. //
  61. // Description : Calculates the CRC32 of a data object using the default seed and polynomial.
  62. //
  63. // Declaration : -(uint32_t)crc32;
  64. //
  65. // Parameters : None.
  66. //
  67. // Return Value : The CRC32 value.
  68. //***********************************************************************************************************
  69. - (uint32_t)crc32
  70. {
  71. return [self crc32WithSeed:DEFAULT_SEED usingPolynomial:DEFAULT_POLYNOMIAL];
  72. }
  73. //***********************************************************************************************************
  74. // Method : crc32WithSeed:
  75. //
  76. // Description : Calculates the CRC32 of a data object using a supplied seed and default polynomial.
  77. //
  78. // Declaration : -(uint32_t)crc32WithSeed:(uint32_t)seed;
  79. //
  80. // Parameters : seed
  81. // The initial CRC value.
  82. //
  83. // Return Value : The CRC32 value.
  84. //***********************************************************************************************************
  85. - (uint32_t)crc32WithSeed:(uint32_t)seed
  86. {
  87. return [self crc32WithSeed:seed usingPolynomial:DEFAULT_POLYNOMIAL];
  88. }
  89. //***********************************************************************************************************
  90. // Method : crc32UsingPolynomial:
  91. //
  92. // Description : Calculates the CRC32 of a data object using a supplied polynomial and default seed.
  93. //
  94. // Declaration : -(uint32_t)crc32UsingPolynomial:(uint32_t)poly;
  95. //
  96. // Parameters : poly
  97. // The polynomial to use in calculating the CRC.
  98. //
  99. // Return Value : The CRC32 value.
  100. //***********************************************************************************************************
  101. - (uint32_t)crc32UsingPolynomial:(uint32_t)poly
  102. {
  103. return [self crc32WithSeed:DEFAULT_SEED usingPolynomial:poly];
  104. }
  105. //***********************************************************************************************************
  106. // Method : crc32WithSeed:usingPolynomial:
  107. //
  108. // Description : Calculates the CRC32 of a data object using supplied polynomial and seed values.
  109. //
  110. // Declaration : -(uint32_t)crc32WithSeed:(uint32_t)seed usingPolynomial:(uint32_t)poly;
  111. //
  112. // Parameters : seed
  113. // The initial CRC value.
  114. //
  115. // : poly
  116. // The polynomial to use in calculating the CRC.
  117. //
  118. // Return Value : The CRC32 value.
  119. //***********************************************************************************************************
  120. - (uint32_t)crc32WithSeed:(uint32_t)seed usingPolynomial:(uint32_t)poly
  121. {
  122. uint32_t *pTable = (uint32_t *)malloc(sizeof(uint32_t) * 256);
  123. generateCRC32Table(pTable, poly);
  124. uint32_t crc = seed;
  125. uint8_t *pBytes = (uint8_t *)[self bytes];
  126. NSUInteger length = [self length];
  127. while (length--)
  128. {
  129. crc = (crc>>8) ^ pTable[(crc & 0xFF) ^ *pBytes++];
  130. }
  131. free(pTable);
  132. return crc ^ 0xFFFFFFFFL;
  133. }
  134. @end