Mercurial > crc32
diff crc32.c @ 0:422835bc1aca
*: checkin
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 09 Feb 2026 01:15:00 -0500 |
| parents | |
| children | 6483683ac857 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crc32.c Mon Feb 09 01:15:00 2026 -0500 @@ -0,0 +1,50 @@ +#include "crc32.h" +#include "crc32i.h" +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <assert.h> +#include <stdlib.h> +#include <time.h> + +/* Align to a byte offset using the given crc function. */ +static void crc32_align(uint32_t *crc, crc32_r_spec crcfunc, size_t align, const unsigned char **message, size_t *sz) +{ + size_t sz8, szs; + + /* Alignment check */ + if (ALIGNED(*message, align)) + return; + + /* Calculate size needed to align */ + sz8 = align - ((uintptr_t)message % align); + szs = MIN(*sz, sz8); + + *crc = crcfunc(*crc, *message, sz8); + *message += sz8; + *sz -= sz8; + + if (szs == sz8) assert(ALIGNED(*message, align)); +} + +CRC32_API +uint32_t crc32(const unsigned char *message, size_t sz) +{ + uint32_t crc; + size_t i; + + if (!sz) + return 0; + + crc = 0xFFFFFFFF; + crc32_align(&crc, crc32c_r, ALIGNOF(uint32_t), &message, &sz); + if (!sz) return ~crc; +#ifdef __x86_64__ + crc32_align(&crc, crc32qw_r, 16, &message, &sz); + if (!sz) return ~crc; + + return ~crc32x86_vpclmulqdq_r(crc, message, sz); +#else + return ~crc32qw_r(crc, message, sz); +#endif +}
