2 * CRC32 (Castagnoli 1993)
4 * Based on Michael E. Kounavis and Frank L. Berry: A Systematic Approach
5 * to Building High Performance Software-based CRC Generators
6 * (Proceedings of the 10th IEEE Symposium on Computers and Communications 2005)
8 * Includes code from http://sourceforge.net/projects/slicing-by-8/,
9 * which carried the following copyright notice:
11 * Copyright (c) 2004-2006 Intel Corporation - All Rights Reserved
13 * This software program is licensed subject to the BSD License,
14 * available at http://www.opensource.org/licenses/bsd-license.html
16 * Adapted for LibUCW by Martin Mares <mj@ucw.cz> in 2012.
21 #include <ucw/crc-tables.h>
23 static void crc32_update_by1(crc32_context *ctx, const byte *buf, uint len)
27 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
31 static void crc32_update_by4(crc32_context *ctx, const byte *buf, uint len)
33 uint init_bytes, words;
42 // Align start address to a multiple of 4 bytes
43 init_bytes = ((uintptr_t) buf) & 3;
46 init_bytes = 4 - init_bytes;
49 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
52 // Process 4 bytes at a time
55 buf32 = (const u32 *) buf;
59 term1 = crc_tableil8_o56[crc & 0x000000FF] ^ crc_tableil8_o48[(crc >> 8) & 0x000000FF];
62 crc_tableil8_o40[term2 & 0x000000FF] ^
63 crc_tableil8_o32[(term2 >> 8) & 0x000000FF];
66 // Process remaining up to 7 bytes
67 buf = (const byte *) buf32;
70 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
75 static void crc32_update_by8(crc32_context *ctx, const byte *buf, uint len)
77 uint init_bytes, quads;
86 // Align start address to a multiple of 8 bytes
87 init_bytes = ((uintptr_t) buf) & 7;
90 init_bytes = 8 - init_bytes;
93 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
96 // Process 8 bytes at a time
99 buf32 = (const u32 *) buf;
103 term1 = crc_tableil8_o88[crc & 0x000000FF] ^
104 crc_tableil8_o80[(crc >> 8) & 0x000000FF];
107 crc_tableil8_o72[term2 & 0x000000FF] ^
108 crc_tableil8_o64[(term2 >> 8) & 0x000000FF];
109 term1 = crc_tableil8_o56[*buf32 & 0x000000FF] ^
110 crc_tableil8_o48[(*buf32 >> 8) & 0x000000FF];
112 term2 = *buf32 >> 16;
115 crc_tableil8_o40[term2 & 0x000000FF] ^
116 crc_tableil8_o32[(term2 >> 8) & 0x000000FF];
120 // Process remaining up to 7 bytes
121 buf = (const byte *) buf32;
124 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
130 crc32_init(crc32_context *ctx, uint crc_mode)
132 ctx->state = 0xffffffff;
135 case CRC_MODE_DEFAULT:
136 ctx->update_func = crc32_update_by4;
139 ctx->update_func = crc32_update_by1;
142 ctx->update_func = crc32_update_by8;
150 crc32_hash_buffer(const byte *buf, uint len)
153 crc32_init(&ctx, CRC_MODE_DEFAULT);
154 crc32_update(&ctx, buf, len);
155 return crc32_final(&ctx);
163 int main(int argc, char **argv)
166 die("Usage: crc-t <alg> <len> <block> <iters>");
167 uint alg = atoi(argv[1]);
168 uint len = atoi(argv[2]);
169 uint block = atoi(argv[3]);
170 uint iters = atoi(argv[4]);
172 byte *buf = xmalloc(len);
173 for (uint i=0; i<len; i++)
174 buf[i] = i ^ (i >> 5) ^ (i >> 11);
176 for (uint i=0; i<iters; i++)
179 uint modes[] = { CRC_MODE_DEFAULT, CRC_MODE_SMALL, CRC_MODE_BIG };
180 ASSERT(alg < ARRAY_SIZE(modes));
181 crc32_init(&ctx, modes[alg]);
182 for (uint p=0; p<len;)
184 uint l = MIN(len-p, block);
185 crc32_update(&ctx, buf+p, l);
188 uint crc = crc32_final(&ctx);
190 printf("%08x\n", crc);