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;
35 u32 term1, term2, *buf32;
41 // Align start address to a multiple of 4 bytes
42 init_bytes = ((uintptr_t) buf) & 3;
45 init_bytes = 4 - init_bytes;
48 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
51 // Process 4 bytes at a time
58 term1 = crc_tableil8_o56[crc & 0x000000FF] ^ crc_tableil8_o48[(crc >> 8) & 0x000000FF];
61 crc_tableil8_o40[term2 & 0x000000FF] ^
62 crc_tableil8_o32[(term2 >> 8) & 0x000000FF];
65 // Process remaining up to 7 bytes
69 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
74 static void crc32_update_by8(crc32_context *ctx, const byte *buf, uint len)
76 uint init_bytes, quads;
78 u32 term1, term2, *buf32;
84 // Align start address to a multiple of 8 bytes
85 init_bytes = ((uintptr_t) buf) & 7;
88 init_bytes = 8 - init_bytes;
91 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
94 // Process 8 bytes at a time
101 term1 = crc_tableil8_o88[crc & 0x000000FF] ^
102 crc_tableil8_o80[(crc >> 8) & 0x000000FF];
105 crc_tableil8_o72[term2 & 0x000000FF] ^
106 crc_tableil8_o64[(term2 >> 8) & 0x000000FF];
107 term1 = crc_tableil8_o56[*buf32 & 0x000000FF] ^
108 crc_tableil8_o48[(*buf32 >> 8) & 0x000000FF];
110 term2 = *buf32 >> 16;
113 crc_tableil8_o40[term2 & 0x000000FF] ^
114 crc_tableil8_o32[(term2 >> 8) & 0x000000FF];
118 // Process remaining up to 7 bytes
119 buf = (byte *) buf32;
122 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
128 crc32_init(crc32_context *ctx, uint crc_mode)
130 ctx->state = 0xffffffff;
133 case CRC_MODE_DEFAULT:
134 ctx->update_func = crc32_update_by4;
137 ctx->update_func = crc32_update_by1;
140 ctx->update_func = crc32_update_by8;
148 crc32_hash_buffer(const byte *buf, uint len)
151 crc32_init(&ctx, CRC_MODE_DEFAULT);
152 crc32_update(&ctx, buf, len);
153 return crc32_final(&ctx);
161 int main(int argc, char **argv)
164 die("Usage: crc-t <alg> <len> <block> <iters>");
165 uint alg = atoi(argv[1]);
166 uint len = atoi(argv[2]);
167 uint block = atoi(argv[3]);
168 uint iters = atoi(argv[4]);
170 byte *buf = xmalloc(len);
171 for (uint i=0; i<len; i++)
172 buf[i] = i ^ (i >> 5) ^ (i >> 11);
174 for (uint i=0; i<iters; i++)
177 uint modes[] = { CRC_MODE_DEFAULT, CRC_MODE_SMALL, CRC_MODE_BIG };
178 ASSERT(alg < ARRAY_SIZE(modes));
179 crc32_init(&ctx, modes[alg]);
180 for (uint p=0; p<len;)
182 uint l = MIN(len-p, block);
183 crc32_update(&ctx, buf+p, l);
186 uint crc = crc32_final(&ctx);
188 printf("%08x\n", crc);