fork download
  1.  
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. typedef unsigned int uint;
  6. typedef unsigned char byte;
  7.  
  8. void init_crc32( void );
  9. void init_crc32_merge( void );
  10. uint crc32_merge( uint crc1, uint crc2, uint len2 );
  11.  
  12. uint crc32_update( uint x, byte c );
  13. uint strcrc( char* s ) { uint x; for( x=0; *s++; x=crc32_update(x,s[-1]) ); return x; }
  14.  
  15. int main( void ) {
  16. init_crc32();
  17. init_crc32_merge();
  18.  
  19. char str1[] = "Hello";
  20. char str2[] = " World!!!";
  21. char str3[256] = "";
  22. strcat(str3,str1);
  23. strcat(str3,str2);
  24.  
  25. uint c1 = strcrc(str1), l1 = strlen(str1);
  26. uint c2 = strcrc(str2), l2 = strlen(str2);
  27. uint c3 = strcrc(str3), l3 = strlen(str3);
  28.  
  29. printf( "CRC32('%s')=%08X\n", str1, c1 );
  30. printf( "CRC32('%s')=%08X\n", str2, c2 );
  31. printf( "CRC32('%s')=%08X\n", str3, c3 );
  32.  
  33. printf( "crc32_merge(%08X,%08X,%i)=%08X\n", c1,c2,l2, crc32_merge(c1,c2,l2) );
  34.  
  35. }
  36.  
  37. uint CRCTab[256];
  38.  
  39. void init_crc32( void ) {
  40. uint i, j, c;
  41. for( i=0; i<256; i++ ) {
  42. for( c=i,j=0; j<8; j++ ) c=(c&1) ? (c>>1)^0xEDB88320L : (c>>1);
  43. CRCTab[i^0xFF] = c ^ 0xFF000000;
  44. }
  45. }
  46.  
  47. uint crc32_update( uint x, byte c ) { return CRCTab[byte(x)^c] ^ (x>>8); }
  48.  
  49. enum{ CRC_LEN=32 };
  50.  
  51. uint crc_mul( uint crc, uint (&mat)[CRC_LEN] ) {
  52. uint i, out=0;
  53. // for( i=0; i<32; i++ ) if( crc&(1<<i) ) out ^= mat[i];
  54. for( i=0; crc; i++,crc>>=1 ) if( crc&1 ) out ^= mat[i];
  55. return out;
  56. }
  57.  
  58. void crc_set( uint (&out)[CRC_LEN], uint (&inp)[CRC_LEN] ) {
  59. for( uint i=0; i<CRC_LEN; i++ ) out[i]=inp[i];
  60. }
  61.  
  62. void crc_sqr( uint (&mat)[CRC_LEN] ) {
  63. uint i, square[CRC_LEN];
  64. for( i=0; i<CRC_LEN; i++ ) square[i] = crc_mul( mat[i], mat );
  65. crc_set( mat, square );
  66. }
  67.  
  68. uint crc_pad[CRC_LEN][CRC_LEN];
  69.  
  70. void init_crc32_merge( void ) {
  71. uint i,mat[CRC_LEN];
  72. // matrix for adding 1 zero bit to crc
  73. mat[0] = 0xEDB88320; // CRC32 polynomial
  74. for( i=1; i<CRC_LEN; i++ ) mat[i] = 1<<(i-1);
  75. crc_sqr(mat); // 2 bits
  76. crc_sqr(mat); // 4 bits
  77. crc_sqr(mat); // 8 bits
  78. for( i=0; i<CRC_LEN; i++ ) crc_set(crc_pad[i],mat), crc_sqr(mat);
  79. }
  80.  
  81. uint crc32_merge( uint crc1, uint crc2, uint len2 ) {
  82. // for( uint i=0; i<CRC_LEN; i++ ) if( len2 & (1<<i) ) crc1=crc_mul(crc1,crc_pad[i]);
  83. for( uint i=0; len2; i++,len2>>=1 ) if( len2&1 ) crc1=crc_mul(crc1,crc_pad[i]);
  84. return crc1 ^ crc2;
  85. }
  86.  
  87.  
  88.  
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
CRC32('Hello')=F7D18982
CRC32(' World!!!')=11F02F66
CRC32('Hello World!!!')=1004B80E
crc32_merge(F7D18982,11F02F66,9)=1004B80E