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, uns len)
27 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
31 static void crc32_update_by4(crc32_context *ctx, const byte *buf, uns len)
33 uns init_bytes, words;
35 u32 term1, term2, *buf32;
37 // Align start address to a multiple of 4 bytes
38 init_bytes = ((uintptr_t) buf) & 3;
41 init_bytes = 4 - init_bytes;
44 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
47 // Process 4 bytes at a time
54 term1 = crc_tableil8_o56[crc & 0x000000FF] ^ crc_tableil8_o48[(crc >> 8) & 0x000000FF];
57 crc_tableil8_o40[term2 & 0x000000FF] ^
58 crc_tableil8_o32[(term2 >> 8) & 0x000000FF];
61 // Process remaining up to 7 bytes
64 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
69 static void crc32_update_by8(crc32_context *ctx, const byte *buf, uns len)
71 uns init_bytes, quads;
73 u32 term1, term2, *buf32;
75 // Align start address to a multiple of 8 bytes
76 init_bytes = ((uintptr_t) buf) & 7;
79 init_bytes = 8 - init_bytes;
82 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
85 // Process 8 bytes at a time
92 term1 = crc_tableil8_o88[crc & 0x000000FF] ^
93 crc_tableil8_o80[(crc >> 8) & 0x000000FF];
96 crc_tableil8_o72[term2 & 0x000000FF] ^
97 crc_tableil8_o64[(term2 >> 8) & 0x000000FF];
98 term1 = crc_tableil8_o56[*buf32 & 0x000000FF] ^
99 crc_tableil8_o48[(*buf32 >> 8) & 0x000000FF];
101 term2 = *buf32 >> 16;
104 crc_tableil8_o40[term2 & 0x000000FF] ^
105 crc_tableil8_o32[(term2 >> 8) & 0x000000FF];
109 // Process remaining up to 7 bytes
110 buf = (byte *) buf32;
112 crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
118 crc32_init(crc32_context *ctx, uns crc_mode)
120 ctx->state = 0xffffffff;
123 case CRC_MODE_DEFAULT:
124 ctx->update_func = crc32_update_by4;
127 ctx->update_func = crc32_update_by1;
130 ctx->update_func = crc32_update_by8;
138 crc32_hash_buffer(const byte *buf, uns len)
141 crc32_init(&ctx, CRC_MODE_DEFAULT);
142 crc32_update(&ctx, buf, len);
143 return crc32_final(&ctx);
151 int main(int argc, char **argv)
154 die("Usage: crc-t <alg> <len> <block> <iters>");
155 uns alg = atoi(argv[1]);
156 uns len = atoi(argv[2]);
157 uns block = atoi(argv[3]);
158 uns iters = atoi(argv[4]);
160 byte *buf = xmalloc(len);
161 for (uns i=0; i<len; i++)
162 buf[i] = i ^ (i >> 5) ^ (i >> 11);
164 for (uns i=0; i<iters; i++)
167 uns modes[] = { CRC_MODE_DEFAULT, CRC_MODE_SMALL, CRC_MODE_BIG };
168 ASSERT(alg < ARRAY_SIZE(modes));
169 crc32_init(&ctx, modes[alg]);
170 for (uns p=0; p<len;)
172 uns l = MIN(len-p, block);
173 crc32_update(&ctx, buf+p, l);
176 uns crc = crc32_final(&ctx);
178 printf("%08x\n", crc);